IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Update un champ à partir d'un count effectué sur une autre table selon certain conditions


Sujet :

Langage SQL

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2013
    Messages : 7
    Points : 7
    Points
    7
    Par défaut Update un champ à partir d'un count effectué sur une autre table selon certain conditions
    Salut tout le monde,

    J'essaie de mettre à jour un champ dans le tableau A avec un certain nombre d'occurrences de certaines données dans une autre table B. La condition est que les champs de B doivent avoir les mêmes clés étrangères que dans le tableau A.
    merci à adavance

    Nom : Capture.PNG
Affichages : 1637
Taille : 20,4 Ko

    j'aimerais faire ce COUNT :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select        COUNT(1) as NbrFacture,DateFacturation_FK, Site_FK, Client_FK
                from        DistrisysDW.dbo.FactFacture
                group by    DateFacturation_FK, Site_FK, Client_FK
                order by    2

    Et mettre à jour "NbFacture" dans l'autre table dans un état que les lignes correspondent à ces trois champs DateFacturation_FK, Site_FK, Client_FK.

    J'ai essayé ça mais ça ne fonctionne pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Update        DistrisysDW.dbo.FactFactureEntete
    SET            NumFacture=T.NbrFacture
    from        
                (select        COUNT(1) as NbrFacture,DateFacturation_FK, Site_FK, Client_FK
                from        DistrisysDW.dbo.FactFacture
                group by    DateFacturation_FK, Site_FK, Client_FK
                order by    2
               ;) T
    INNER JOIN    DistrisysDW.dbo.FactFactureEntete ENT ON T.DateFacturation_FK=ENT.DateFacturation_FK 
    AND            T.Site_FK=ENT.Site_FK AND T.Client_FK=ENT.Client_FK
    Images attachées Images attachées  

  2. #2
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 790
    Points
    6 790
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    2 petites remarques.

    Il est impossible, et surtout particulièrement inutile de placer un ORDER BY dans une sous requête. Quoi qu'il se passe, l'ensemble des données sera traité, qu'importe l'ordre, c'est de la cosmétique qui ne devrais pas se gérer en SQL.

    Lorsqu'on fait un UPDATE, la fonction SET se comporte ainsi.

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    UPDATE maTable
        SET ChampDeMaTableAUpdate = ChampDeLaSource
    Dans votre cas, vous avez fait quelques mélanges, il me semble, entre votre modèle et votre besoin.

    Vous dites vouloir mettre à jour la colonne NbFacture de la table Entete, cependant, votre code ne correspond pas
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SET NumFacture = T.NbrFacture

    Probablement une confusion de champ.

    Pour votre solution, je vous propose quelque chose comme ça

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    WITH COUNT_Facture AS (
    SELECT DateFacturation_FK
         , Site_FK
         , Client_FK
         , COUNT(*) AS NbrFacture
      FROM DistrisysDW.dbo.FactFacture
     GROUP BY DateFacturation_FK, Site_FK, Client_FK )
     
    UPDATE F
       SET NbFacture = NbrFacture
      FROM COUNT_Facture CF
           INNER JOIN DistrisysDW.dbo.FactFactureEntete F ON CF.DateFacturation_FK = F.DateFacturation_FK
                                                         AND CF.Site_FK = F.Site_FK
                                                         AND CF.Client_FK = F.Client_FK;

    Avec une CTE qui va agréger vos données et que l'on va exploiter dans le FROM.

    Attention cependant, vous êtes dans le langage SQL, un FROM n'est pas une norme SQL mais une largesse de SQL Server.

    Cordialement,
    Lyche

  3. #3
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Juste une petite remarque concernant ce que vous cherchez à faire.

    Vous cherchez à stocker une valeur calculée.
    C'est tout à votre honneur, j'imagine dans une optique d'optimisation ou de simplification de certaines requêtes.
    Cependant, ce n'est pas une bonne pratique, car il y a peu de chances pour que vous arriviez à maintenir l'intégrité à tout instant des données.

    Et parfois, il faut mieux attendre 2 secondes de plus et avoir un résultat juste plutôt que de se précipiter et avoir un résultat faux.

    Donc, en premier lieux, évitez autant que possible de stocker des valeurs calculées.
    Si vraiment vous ne pouvez pas faire autrement, optez en priorité, si votre SGBD le permet, pour des colonnes calculées : elles ont l'avantage de pouvoir être persistantes (si leur type et le calcul le permet) et surtout, garantissent une intégrité à tout instant.
    Si votre SGBD ne supporte pas les colonnes calculées, alors optez en priorité pour une vue : le principal inconvénient par rapport à une colonne calculée, c'est que le calcul est fait à chaque accès à la vue, même si on ne lit pas la colonne.
    Et si vraiment c'est les performances qui sont vitales, optez pour une mise à jour de cette colonne par trigger.

    Ne remplissez jamais une colonne calculée par requête de type "one shot". Car les données sont alors potentiellement incohérentes (et donc fausses) instantanément après la lecture.

  4. #4
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Sinon, pour répondre à la requête oneshot, en plus simple :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    update FactFactureEntete f1
    set nbfacture = (select COUNT(*) from FactFacture f2 where f2.DateFacturation_FK = f1.DateFacturation_FK AND f2.Site_FK = f1.Site_FK AND f2.Client_FK = f1.Client_FK),
    nbarticle = (select sum(quantite) from FactFacture f2 where f2.DateFacturation_FK = f1.DateFacturation_FK AND f2.Site_FK = f1.Site_FK AND f2.Client_FK = f1.Client_FK)

    Plus simple à mon avis.

  5. #5
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 790
    Points
    6 790
    Billets dans le blog
    4
    Par défaut
    heu, pourquoi la somme?

    Et oui, j'ai hésité à proposer la solution avec la requête dans le SET. J'ai simplement voulu conserver en partie sa syntaxe.

    Cependant, je ne vois pas où se trouve la somme

  6. #6
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Bah le count(*) c'est pour compter les factures.
    Et le sum(quantite) c'est pour remplir la colonne "nbrarticlefacture".

  7. #7
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 790
    Points
    6 790
    Billets dans le blog
    4
    Par défaut
    Justement, je ne vois pas ce besoin dans sa demande, mais je suis peut-être juste fou

    Ou est-ce simplement une anticipation, qui serait bien vue dans ce cas

  8. #8
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    C'est une anticipation

Discussions similaires

  1. Réponses: 7
    Dernier message: 05/06/2008, 13h54
  2. UPDATE sur une autre table
    Par ftoutin dans le forum SQL
    Réponses: 4
    Dernier message: 12/02/2008, 12h37
  3. Réponses: 2
    Dernier message: 09/01/2008, 10h56
  4. Réponses: 11
    Dernier message: 08/01/2008, 11h36
  5. Tester si un couple de champs existe sur une autre table
    Par jerjerrod dans le forum Langage SQL
    Réponses: 5
    Dernier message: 06/02/2007, 18h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo