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 :

requête avec 2 critères obligatoire


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 80
    Points : 43
    Points
    43
    Par défaut requête avec 2 critères obligatoire
    Bonjour,

    Nouveau venu sur le forum je vais essayer de vous expliquer mon problème. Je travaille sur des base de données via SQLTOOLS.
    J'ai besoin dans le cadre d'une étude de faire une recherche sur les personnes qui ont été payées au mois de décembre 2007 et décembre 2008. J'ai donc construit ma requête avec mes critères de filtre mais je ne sais pas comment faire pour obtenir ceux qui sont payé en 2007 et 2008.
    Dans ma requête j'ai le résultat si la personne existe dans l'une ou l'autre des années. Moi je veux que la personne soit présentes dans les deux années obligatoirement et pas que dans une.
    Voici mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT * 
    FROM personnel
    WHERE ANNEE IN (2007,2008)

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Bonjour,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT * 
    FROM personnel
    WHERE ANNEE IN (2007,2008)
    GROUP BY ...
    HAVING COUNT(DISTINCT ANNEE) = 2
    Comme vous n'avez pas décrit votre table, il sera difficile de vous dire quoi mettre dans le GROUP BY.

  3. #3
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 80
    Points : 43
    Points
    43
    Par défaut
    Bonjour Snipah,

    Tout d'abord merci de ton aide, j'ai juste une question est-il possible de mettre uniquement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HAVING DISTINCT ANNEE = 2
    Ou suis je obliger de mettre le COUNT ?

    Je reprends mon post juste pour essayer de comprendre. Le HAVING oblige d'avoir 2 en résultat, sur le comptage des années.
    Je connaissais pas cette fonction.

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur
    Inscrit en
    Juin 2006
    Messages
    645
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Juin 2006
    Messages : 645
    Points : 709
    Points
    709
    Par défaut
    Count permet de compter. Il est donc nécessaire ici.
    Utiliser ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HAVING DISTINCT ANNEE = 2
    n'a pas de grand sens... et restreindrait à l'an 2.

    A la rigueur, pour bien comprendre tout ça, n'hésite pas à lancer les requêtes pour voir ce qu'elles donnent.
    Quand tu fais un SELECT, il n'y a aucun risque pour ta base !
    « Se demander si un ordinateur peut penser est aussi intéressant que de se demander si un sous-marin peut nager. »
    -- Edsger Dijkstra

  5. #5
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 80
    Points : 43
    Points
    43
    Par défaut
    Ma requête compléte:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT DISTINCT (table1.identif), table1.col1, table1.col2, table1.col3, Sum (table1.mt_indem),table1.col_annee 
    FROM table1, table2
    WHERE table2.identif = table1.identif 
    AND table2.col3 = table1.col3 
    AND table2,col_annee = table1.col_annee 
    AND table2.col4 = 10 
    AND table1.col5 = 0 
    AND table1.col6 BETWEEN 100 AND 410 
    AND table1.col3 = 12 
    AND table1.col_annee IN (2007,2008)
    GROUP BY table1.indentif, table1.col1,table1.col2,table1.col3,table1.col_annee
    HAVING COUNT(DISTINCT col_annee) = 2
    Mais cette requête ne me ramène pas de résultat

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Deja, vous avez une virgule à la place d'un point sur la troisième condition de la clause WHERE.
    Ensuite, si on ne sait pas ce que vous avez dans vos tables, on pourra difficilement vous dire pourquoi vous n'avez pas de résultat.

  7. #7
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 80
    Points : 43
    Points
    43
    Par défaut
    Bonjour Snipah,

    Oui c'est une erreur de recopie, j'ai bien un point dans mon essai. Ma requête ne fonctionne pas et je me posais une question? Ne faut-il pas que mon having soit sur le DISTINCT (table1.identif) du SELECT plutôt que sur DISTINCT (table1.identif)??

  8. #8
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Essayez ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT table1.identif, table1.col1, table1.col2, table1.col3, sum(table1.mt_indem)
    FROM table1, table2
    WHERE table2.identif = table1.identif 
    AND table2.col3 = table1.col3 
    AND table2,col_annee = table1.col_annee 
    AND table2.col4 = 10 
    AND table1.col5 = 0 
    AND table1.col6 BETWEEN 100 AND 410 
    AND table1.col3 = 12 
    AND table1.col_annee IN (2007,2008)
    GROUP BY table1.indentif, table1.col1,table1.col2,table1.col3
    HAVING COUNT(DISTINCT table1.col_annee) = 2

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    A priori non, c'est bien sur l'année que ça doit porter.
    Déja, précisez la table de laquelle vient la colonne ANNEE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HAVING COUNT(DISTINCT table1.col_annee) = 2
    Ceci dit, si vous incluez l'année dans le GROUP BY, c'est sûr qu'aucune ligne de votre groupe ne contiendra les deux années.

    Encore une fois, on ne pourra pas vous aider plus efficacement si on ne sait pas ce que contient votre table, surtout qu'avec des noms de colonne comme 'col1' ou 'col4', on pourra difficilement deviner.

    EDIT : Encore grillé

  10. #10
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 80
    Points : 43
    Points
    43
    Par défaut
    Bonjour à tous,

    J'ai effectivement dans ma requête le champ année dans mon GROUP BY.
    Je vais faire l'essai sans. Pour être plus explicite voici la requête en language claire. Par contre il me faut l'année dans mon résultat.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT DISTINCT(INDEMNITE.identif),INDEMNITE.CAT_BUD,INDEMNITE.C_GRADE,INDEMNITE.MM_INDEM, Sum (INDEMNITE.mt_indem), INDEMNITE.AN_INDEM 
    FROM indemnite, personnel
    WHERE  PERSONNEL.identif = INDEMNITE.identif 
    AND PERSONNEL.MOIS = INDEMNITE.MM_INDEM 
    AND PERSONNEL.ANNEE = INDEMNITE.AN_INDEM  
    AND PERSONNEL.C_POSIT = 10 
    AND INDEMNITE.C_TERRIT = 0 
    AND INDEMNITE.C_INDEM BETWEEN 100 AND 410 
    AND INDEMNITE.MM_INDEM = 12 
    AND INDEMNITE.AN_INDEM IN (2007,2008)
    GROUP BY INDEMNITE.identif, INDEMNITE.CAT_BUD,INDEMNITE.C_GRADE,INDEMNITE.MM_INDEM
    HAVING COUNT(DISTINCT INDEMNITE.AN_INDEM) =2

  11. #11
    Membre éclairé
    Homme Profil pro
    Développeur
    Inscrit en
    Juin 2006
    Messages
    645
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Juin 2006
    Messages : 645
    Points : 709
    Points
    709
    Par défaut
    S'il te faut l'année, rajoute la simplement dans la clause SELECT de la requête...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT ..., ..., PERSONNEL.ANNEE
    ...
    « Se demander si un ordinateur peut penser est aussi intéressant que de se demander si un sous-marin peut nager. »
    -- Edsger Dijkstra

  12. #12
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 80
    Points : 43
    Points
    43
    Par défaut
    Bonjour,

    Et dans le GROUP BY je mets quoi??
    INDEMNITE.AN_INDEM ?

  13. #13
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Je crois que vous exprimez mal votre besoin.

    Ce qui m'amène à penser celà c'est votre premier distinct (inutile, je pense que vous avez mal compris son utilisation) et le fait de vouloir les années dans votre résultat final.

    Les années dans le résultat final est plus ou moins incompatible avec le prédicat payé en 2007 et 2008.

    Essayez de segmenter votre besoin au niveau le plus fin, puis de reconstruire ce qu'il y a autour. Votre point de départ sont les personnes payées en 2007 et 2008. Que voulez-vous savoir sur ces personnes ?

  14. #14
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 80
    Points : 43
    Points
    43
    Par défaut
    Bonjour Waldar,

    Peut-être me suis-je mal exprimer. Ce que je veux faire:
    1- Connaitre une partie des indemnités de traitement des employés.

    Le tout afin de faire une comparaison entre le salaire de décembre 2007 et celui de 2008. Je dois ensuite classer par catégorie de grade pour exprimer le surcout dans chaque catégorie. Le reste je le fais avec Excel.
    Cordialement

  15. #15
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Merci, c'est nettemement plus précis !
    Dites-moi ce que vous pensez de ce code :
    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
    27
    28
    29
    30
    31
    select
        idm.identif,
        idm.cat_bud,
        idm.c_grade,
        idm.mm_indem,
        sum(case idm.an_indem when 2007 then idm.mt_indem else 0 end) as mt_indem_2007,
        sum(case idm.an_indem when 2008 then idm.mt_indem else 0 end) as mt_indem_2008
    from
        indemnite idm
        inner join personnel per
          on per.identif = idm.identif
         and per.mois = idm.mm_indem
         and per.annee = idm.an_indem  
    where
        per.c_posit = 10 
    and idm.c_territ = 0 
    and idm.c_indem between 100 and 410 
    and idm.mm_indem = 12 
    and idm.an_indem in (2007,2008)
    group by
        idm.identif,
        idm.cat_bud,
        idm.c_grade,
        idm.mm_indem
    having
        count(distinct idm.an_indem) = 2
    order by
        idm.identif asc,
        idm.cat_bud asc,
        idm.c_grade asc,
        idm.mm_indem asc

  16. #16
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 80
    Points : 43
    Points
    43
    Par défaut
    Bonjour Waldar ,

    Super ta requête, elle fonctionne bien. Je voudrais juste savoir si j'ai un risque d'erreur. Si un personnel qui a été promu et qui a changé de grade entre 2007 et 2008 se trouve t-il dans ma requête? J'ai peur d'en oublier.
    Par ailleurs je ne connaissais pas la commande entre parenthèse dans cette ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sum(case idm.an_indem when 2007 then idm.mt_indem else 0 end) AS mt_indem_2007
    Merci pour vos réponses

  17. #17
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Etant donné que le grade fait partie du groupement, si un employé a changé de grade d'une année sur l'autre, tu auras deux groupes pour cet employé, avec un count(DISTINCT idm.an_indem) = 1.
    Il n'apparaitra donc pas dans le resultat.

    Le plus sur dans ce cas est de récupérer les infos susceptibles de changer d'une année sur l'autre après le regroupement, en utilisant une jointure sur "identif".

  18. #18
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 80
    Points : 43
    Points
    43
    Par défaut
    Bonjour Snipah

    Je ne suis pas sur de te comprendre. Ma jointure sur "identif", il me semble quelle existe . Ce que je suis sur, c'est que des personnels ont changé de grade au cours de l'année. Je requête le grade pour les classer ultérieurement dans excel. L'idéal c'est de garder uniquement le dernier grade connu en décembre 2008, celui de 2007 sera systématiquement un grade inférieur.

  19. #19
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    En fait, l'idée est de sortir le grade du regroupement, étant donné qu'il peut changer d'une année sur l'autre, et donc fausser tes résultats.

    Donc, soit tu fais d'abord ton regroupement, puis tu refais une jointure pour obtenir le(s) grade(s) correspondant à chaque employés, soit tu inclus le grade dans ton agrégat.
    Mais pour ça, il faut savoir quel grade garder si on en a plusieurs pour un même employé. Tu nous dis
    L'idéal c'est de garder uniquement le dernier grade connu en décembre 2008, celui de 2007 sera systématiquement un grade inférieur
    Ce qui signifie? Si le grade est représenté par une valeur numérique, tu peux peut être récupérer max(grade).
    En reprenant la requête proposée par Waldar, ça donne :
    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
    27
    28
    29
    SELECT
        idm.identif,
        idm.cat_bud,
        max(idm.c_grade) as c_grade,
        idm.mm_indem,
        sum(case idm.an_indem when 2007 then idm.mt_indem else 0 end) AS mt_indem_2007,
        sum(case idm.an_indem when 2008 then idm.mt_indem else 0 end) AS mt_indem_2008
    FROM
        indemnite idm
        INNER JOIN personnel per
          ON per.identif = idm.identif
         AND per.mois = idm.mm_indem
         AND per.annee = idm.an_indem  
    WHERE
        per.c_posit = 10 
    AND idm.c_territ = 0 
    AND idm.c_indem BETWEEN 100 AND 410 
    AND idm.mm_indem = 12 
    AND idm.an_indem IN (2007,2008)
    GROUP BY
        idm.identif,
        idm.cat_bud,
        idm.mm_indem
    HAVING
        count(DISTINCT idm.an_indem) = 2
    ORDER BY
        idm.identif ASC,
        idm.cat_bud ASC,
        idm.mm_indem ASC
    Si ça ne convient pas, il faudra sortir le grade du regroupement, puis le récupérer dans un second temps.

  20. #20
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Dans ce cas essayez-ceci :
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    SELECT
        SR.identif,
        idn.cat_bud,
        idn.c_grade,
        idn.mm_indem,
        SR.mt_indem_2007,
        SR.mt_indem_2008
    FROM
        indemnite idn
        INNER JOIN
        (
        SELECT
            idm.identif,
            sum(case idm.an_indem when 2007 then idm.mt_indem else 0 end) AS mt_indem_2007,
            sum(case idm.an_indem when 2008 then idm.mt_indem else 0 end) AS mt_indem_2008
        FROM
            indemnite idm
            INNER JOIN personnel per
              ON per.identif = idm.identif
             AND per.mois = idm.mm_indem
             AND per.annee = idm.an_indem  
        WHERE
            per.c_posit = 10 
        AND idm.c_territ = 0 
        AND idm.c_indem BETWEEN 100 AND 410 
        AND idm.mm_indem = 12 
        AND idm.an_indem IN (2007,2008)
        GROUP BY
            idm.identif
        HAVING
            count(DISTINCT idm.an_indem) = 2
        ) SR
          ON SR.identif = idn.identif
    WHERE
        idn.mm_indem = 12 
    AND idn.an_indem = 2008
    ORDER BY
        SR.identif ASC,
        idn.cat_bud ASC,
        idn.c_grade ASC,
        idn.mm_indem ASC

Discussions similaires

  1. [AC-2003] Requête avec comme critère des dates
    Par Aurooree dans le forum Requêtes et SQL.
    Réponses: 18
    Dernier message: 10/08/2012, 10h36
  2. Réponses: 6
    Dernier message: 23/11/2011, 16h36
  3. Requête avec un critère appartenant à une liste déroulante
    Par liloudris dans le forum Requêtes et SQL.
    Réponses: 15
    Dernier message: 16/09/2009, 05h14
  4. Requête avec en critère une variable globale
    Par mael94420 dans le forum WinDev
    Réponses: 13
    Dernier message: 20/09/2006, 11h29
  5. Requête avec comme critère de recherche un %
    Par Poussy-Puce dans le forum Langage SQL
    Réponses: 1
    Dernier message: 23/03/2006, 20h15

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