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 :

Select unitaire sur une table et count dans 1 autre


Sujet :

SQL Firebird

  1. #1
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 906
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 906
    Points : 6 031
    Points
    6 031
    Par défaut Select unitaire sur une table et count dans 1 autre
    Bonjour,

    Je n'arrive pas (plus?) à coder une telle requête

    Je souhaite avoir les données d'une occurrence (via select sur sa clé) ET le nb de lignes référençant (via FK) cette occurrence depuis une autre table; afin d'obtenir quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data1 data2 ... datan nombre
    Une idée?
    Merci par avance.

    FB2.5 / Firedac
    "Il n'y a pas de bonnes réponses à une mauvaise question." (M. Godet)
    -----------------------
    Pensez à cloturer votre sujet - Aucune réponse aux sollicitations techniques par MP
    Usus magister est optimus

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 157
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 157
    Points : 38 963
    Points
    38 963
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Voici une possibilité :

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    with t1(t1id, t1ch) as
        (select 1, 'truc'     union all
         select 2, 'bidule'   union all
         select 3, 'machin'   union all
         select 4, 'chose'
        )
       , t2 (t2id, t2ch, t1id) as
        (select 1, 'A', 1   union all 
         select 2, 'B', 1   union all
         select 3, 'G', 2   union all
         select 4, 'Y', 4   union all
         select 5, 'H', 2   union all 
         select 6, 'I', 2   union all
         select 7, 'J', 2   union all
         select 8, 'C', 1
        )
    select t1.t1id
         , t1.t1ch
         , count(t2.t2id)
    from t1
    left join t2
       on t2.t1id=t1.t1id
    where t1.t1id=2
    group by t1.t1id
           , t1.t1ch

  3. #3
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 906
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 906
    Points : 6 031
    Points
    6 031
    Par défaut
    Bonjour escartefigue,
    et merci pour ta réponse.

    Instruction confusante en première lecture, mais, ayant constaté l'utilisation explicite du contenu des tables dans l'instruction, j'ai tenté de rendre générique et ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Select 
    t22.DIVE_SITE_ID, t22.SITE_NAME, COUNT(t18.DIVE_ID) as "Nb"
       FROM TAB_DIVE_SITE t22
    JOIN TAB_DIVE t18 on (t18.DIVE_SITE_ID = t22.DIVE_SITE_ID)
     Where t22.DIVE_SITE_ID = 23 
    GROUP BY t22.DIVE_SITE_ID, t22.SITE_NAME
    J'étais sur la bonne piste, mais j'ai du mal à faire cohabiter un "GROUP BY" et un agrégat dans 1 requête (manque de pratique).

    [EDIT]

    Bon, tout se passe bien lorsqu'il y a dans t2 de la matière pour chaque occurrence présente dans t1; mais quand ce n'est pas le cas, l'occurrence de t1 n'apparait pas alors que je souhaite la voir, avec 0
    J'ai tenté un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MAXVALUE(0,COUNT(...)) as "Nb"
    mais rien n'y fait!
    "Il n'y a pas de bonnes réponses à une mauvaise question." (M. Godet)
    -----------------------
    Pensez à cloturer votre sujet - Aucune réponse aux sollicitations techniques par MP
    Usus magister est optimus

  4. #4
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 906
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 906
    Points : 6 031
    Points
    6 031
    Par défaut
    Alors,j'ai fini par trouver une solution peut-être pas très élégante :
    Code : 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
    Select
    t22.DIVE_SITE_ID, t22.AREA_ID,
    t22.SITE_NAME, t22.DESCRIPTION,
    t22.SITE_LATITUDE,
    t22.SITE_LONGITUDE,
    t22.SITE_ELEVATION,
    COUNT(t28.MAP_ID) as "Nb"
       FROM TAB_DIVE_SITE t22
    JOIN TAB_MAP t28 on (t28.DIVE_SITE_ID = t22.DIVE_SITE_ID)
     Where t22.DIVE_SITE_ID <>0
    GROUP BY t22.DIVE_SITE_ID, t22.AREA_ID, t22.SITE_NAME, t22.DESCRIPTION, t22.SITE_LATITUDE, t22.SITE_LONGITUDE, t22.SITE_ELEVATION
    UNION
    Select
    t22.DIVE_SITE_ID, t22.AREA_ID,
    t22.SITE_NAME, t22.DESCRIPTION,
    t22.SITE_LATITUDE,
    t22.SITE_LONGITUDE,
    t22.SITE_ELEVATION,
    0 as "Nb"
       FROM TAB_DIVE_SITE t22
    Where t22.DIVE_SITE_ID NOT IN 
         (SELECT DISTINCT (t28.DIVE_SITE_ID) 
            FROM TAB_MAP t28
         )
      AND t22.DIVE_SITE_ID <>0   
    GROUP BY t22.DIVE_SITE_ID, t22.AREA_ID, t22.SITE_NAME, t22.DESCRIPTION, t22.SITE_LATITUDE, t22.SITE_LONGITUDE, t22.SITE_ELEVATION
    "Il n'y a pas de bonnes réponses à une mauvaise question." (M. Godet)
    -----------------------
    Pensez à cloturer votre sujet - Aucune réponse aux sollicitations techniques par MP
    Usus magister est optimus

  5. #5
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 157
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 157
    Points : 38 963
    Points
    38 963
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par qi130 Voir le message
    Bon, tout se passe bien lorsqu'il y a dans t2 de la matière pour chaque occurrence présente dans t1; mais quand ce n'est pas le cas, l'occurrence de t1 n'apparait pas alors que je souhaite la voir, avec 0
    J'ai tenté un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MAXVALUE(0,COUNT(...)) as "Nb"
    mais rien n'y fait!
    Mais pourquoi se compliquer la vie alors que j'ai donné la solution plus haut qui répond exactement à ce besoin : j'avais justement inclus un cas dans lequel il n'y a aucune correspondance et qui renvoie 0, c'est le cas de T1id=3 ("machin") pour lequel il n'y a rien dans T2

    Votre erreur est d'avoir remplacé la jointure externe de mon exemple (LEFT JOIN) par une jointure interne (JOIN), c'est ce qui provoque ce fonctionnement incorrect.
    Quand on ne le précise pas explicitement, la jointure par défaut est interne (INNER JOIN), d'où la non prise en compte de la ligne en cas de non correspondance.
    Et quand on utilise LEFT ou RIGHT, le mot OUTER est implicite, c'est pourquoi je ne l'avais pas mis, mais la syntaxe complète est bien LEFT OUTER JOIN, donc une jointure externe.

    Reprenez mon exemple sans le moindre changement, tout fonctionne

  6. #6
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 906
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 906
    Points : 6 031
    Points
    6 031
    Par défaut
    Oups !
    Effectivement le LEFT arrange bien les choses !

    Merci d'avoir ... insisté
    "Il n'y a pas de bonnes réponses à une mauvaise question." (M. Godet)
    -----------------------
    Pensez à cloturer votre sujet - Aucune réponse aux sollicitations techniques par MP
    Usus magister est optimus

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment faire un select avancé sur une table PostgreSql ?
    Par paroparo dans le forum Requêtes
    Réponses: 3
    Dernier message: 01/10/2018, 23h11
  2. Select sur une table qui existe dans 2 BDD
    Par Jinkas dans le forum Accès aux données
    Réponses: 7
    Dernier message: 26/06/2013, 19h43
  3. [MySQL] selection aléatoire sur une table d'articles
    Par shakir33 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 16/10/2009, 11h21
  4. Donnée d'une table non utilisée dans d'autres
    Par jgfa9 dans le forum Requêtes
    Réponses: 2
    Dernier message: 21/01/2008, 15h03
  5. Ce qui est dans une table mais pas dans l'autre !
    Par youyoule dans le forum Requêtes
    Réponses: 4
    Dernier message: 30/12/2007, 12h57

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