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

SQL Firebird Discussion :

Faire un Select Count et sous requete?


Sujet :

SQL Firebird

  1. #1
    Membre averti
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Janvier 2007
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Formateur en informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 144
    Points : 337
    Points
    337
    Par défaut Faire un Select Count et sous requete?
    Bonjour,
    Je n'arrive pas a construire une requête qui pourtant me parait simple.
    J'ai 2 table:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Table1:
    Nom
    V_AA01_1
    V_BB07_89
    V_AA01_1
     
    Table2:
    Nom             Qtte_Theorique
    V_BB07_89       2
    V_AA01_1       3
    Je voudrais faire un select qui retourne les Noms ayant une quantité inexacte dans table1 par rapport a la table 2 champ : Qtte_Theorique.
    Par exemple dans le cas ci-dessus, il devrait apparaitre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Nom                  Qtte_theorique            Qtte_Presente
    V_BB07_89                 2                         1
    Pouvez vous m'indiquer le modèle de requête a suive?

    Merci beaucoup

  2. #2
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 786
    Points : 5 918
    Points
    5 918
    Par défaut
    Bonjour,
    Citation Envoyé par jojo86 Voir le message
    Je voudrais faire un select qui retourne les Noms ayant une quantité inexacte dans table1 par rapport a la table 2 champ : Qtte_Theorique.
    Sans optimisation aucune, et en considérant que dans Table2, il y a au moins tous les noms que je suis susceptible de compter dans Table1, je dirais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT
      T2.Nom,
      T2.Qtte_theorique,
      (SELECT COUNT(*) FROM Table1 T1 WHERE T1.Nom = T2.Nom) AS Qtte_presente
    FROM Table2 T2
    WHERE T2.Qtte_theorique <> (SELECT COUNT(*) FROM Table1 T1B WHERE T1B.Nom = T2.Nom)

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 268
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 268
    Points : 41 671
    Points
    41 671
    Billets dans le blog
    64
    Par défaut
    J'aurais plutôt eu tendance a utiliser un FULL JOIN des 2 Tables et un GROUP BY
    mais sans jeu d'essai je ne m'avancerai pas plus

  4. #4
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 786
    Points : 5 918
    Points
    5 918
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    J'aurais plutôt eu tendance a utiliser un FULL JOIN des 2 Tables et un GROUP BY
    mais sans jeu d'essai je ne m'avancerai pas plus
    En effet, en fonction des règles d'alimentation des tables, le comptage pourrait être faussé, d'où ma supposition initiale (dans Table2, il y a au moins tous les noms que je suis susceptible de compter dans Table1).

    Toujours selon ma supposition, j'aurais pu et du écrire cela avec une jointure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT
      T2.Nom,
      T2.Qtte_theorique,
      COUNT(*) AS Qtte_presente
    FROM Table2 T2
    LEFT JOIN Table1 T1 ON T1.Nom = T2.Nom
    GROUP BY T2.Nom, T2.Qtte_theorique
    HAVING T2.Qtte_theorique <> COUNT(*)
    Et encore, dans les 2 cas, je suppose aussi que la colonne Qtte_theorique est NOT NULL...

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 268
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 268
    Points : 41 671
    Points
    41 671
    Billets dans le blog
    64
    Par défaut
    les matins sont plus courageux , j'ai donc fait un petit jeu d'essai pour tester ma théorie . Ayant déjà eu affaire a des inventaires plein de "surprises" je pars du principe plus général ou le théorique TEST1 peux ne pas avoir tout le 'Pointé' TEST2

    Code Jeu d'essai : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    -- Table Qte Theorique
    CREATE TABLE TEST1
    (
      NOM Varchar(5) NOT NULL,
      QTE Smallint,
      CONSTRAINT PK1 PRIMARY KEY (NOM)
    );
     
    INSERT INTO TEST1 (NOM, QTE) VALUES ('A', '5');
    INSERT INTO TEST1 (NOM, QTE) VALUES ('B', '2');
    -- Notez l'absence de 'C' 
    INSERT INTO TEST1 (NOM, QTE) VALUES ('D', '1');
    INSERT INTO TEST1 (NOM, QTE) VALUES ('E', '2');
     
    -- Table de pointage
    CREATE TABLE TEST2
    (
      NOM Varchar(5) NOT NULL,
      INDICE Smallint
    );
     
    INSERT INTO TEST2 (NOM, INDICE) VALUES ('A', '1');
    INSERT INTO TEST2 (NOM, INDICE) VALUES ('A', '2');
    INSERT INTO TEST2 (NOM, INDICE) VALUES ('A', '3');
    INSERT INTO TEST2 (NOM, INDICE) VALUES ('A', '4');
    INSERT INTO TEST2 (NOM, INDICE) VALUES ('A', '5');
    INSERT INTO TEST2 (NOM, INDICE) VALUES ('B', '6');
    -- présence d'un 'C'
    INSERT INTO TEST2 (NOM, INDICE) VALUES ('C', '7');
    -- pas de 'D'
    INSERT INTO TEST2 (NOM, INDICE) VALUES ('E', '8');
    INSERT INTO TEST2 (NOM, INDICE) VALUES ('E', '9');

    Code Test du Full Join : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT T1.NOM,T1.QTE,T2.NOM AS NOMT2 
    FROM TEST1 T1 FULL JOIN TEST2 T2 ON T1.NOM=T2.NOM
    -- Résultat
    T1 T1.Q T2
    A 5 A
    A 5 A
    A 5 A
    A 5 A
    A 5 A
    B 2 B
    [null] [null] C
    E 2 E
    E 2 E
    D 1 [null]
    Résultat souhaité pour les différences
    B 2 / 1
    C 0 / 1
    D 1 / 0

    Code Requête différence : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT COALESCE(T1.NOM,T2.NOM),COALESCE(T1.QTE,0) AS THEORIQUE,Count(*) AS POINTAGE FROM TEST1 T1 FULL JOIN TEST2 T2 ON T1.NOM=T2.NOM
    GROUP BY 1,2
    HAVING COALESCE(T1.QTE,0)<>count(*)
    B 2/1
    C 0/1
    D n'apparait pas ! logique puisque le nombre d'enregistrement est de 1 quand même, le COUNT pose donc problème

    il faut compter le nombre d'enregistrement de T2 et non faire un count globale
    au final :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT COALESCE(T1.NOM,T2.NOM),COALESCE(T1.QTE,0) AS THEORIQUE,Count(T2.INDICE) AS POINTAGE 
    FROM TEST1 T1 FULL JOIN TEST2 T2 
    ON T1.NOM=COALESCE(T2.NOM,T1.NOM)
    GROUP BY 1,2
    HAVING COALESCE(T1.QTE,0)<>count(T2.INDICE)
    Donne le résultat attendu

    Passer par une requête intermédiaire (CTE) peut également être une solution
    plus élégante , surtout si à la place d'un pointage simple (INDICE) on avait un Pointage de Quantités , dans ces cas là remplacé COUNT par SUM et le tour est joué
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    WITH T2 AS (SELECT NOM,COUNT(*) AS POINTAGE FROM TEST2 GROUP BY 1)
    SELECT 
    COALESCE(T1.NOM,T2.NOM),COALESCE(T1.QTE,0) AS THEORIQUE,COALESCE(T2.POINTAGE,0) AS POINTAGE 
    FROM TEST1 T1 FULL JOIN T2 ON T1.NOM=T2.NOM
    WHERE COALESCE(T1.QTE,0)<>COALESCE(T2.POINTAGE,0)
    il semblerait que cette dernière est plus rapide , cependant vu le jeu d'essai ce n'est pas très significatif

Discussions similaires

  1. [TOS 5.3.0] tMSSqlInput - SELECT (TOP 1) + sous requete
    Par Teddy.Legris dans le forum Développement de jobs
    Réponses: 0
    Dernier message: 04/12/2013, 16h05
  2. Faire un select Count et sous requete?
    Par jojo86 dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 30/06/2013, 00h27
  3. Faire un select count(choix) AS nbChoix
    Par Marc22 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 08/08/2011, 12h20
  4. Faire un select count distinct
    Par samsso2006 dans le forum Développement
    Réponses: 9
    Dernier message: 06/07/2010, 21h06
  5. Réponses: 13
    Dernier message: 27/08/2007, 13h16

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