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

Développement SQL Server Discussion :

[SQL SERVER 2008] Requête sur plusieur Tables


Sujet :

Développement SQL Server

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2011
    Messages : 12
    Points : 6
    Points
    6
    Par défaut [SQL SERVER 2008] Requête sur plusieur Tables
    Bonjour à tous,

    Etant débutant en SQL, je bute un peu sur une vue et je n'arrive pas à obtenir ce que je veux.

    J'explique, j'utilise 4 tables : ANIMAL, MUE, NOURRITURE, INFO_SUP qui sont toute liées par ANIMAL.ID

    Je veux afficher ANIMAL.LIBELLE, MUE.DATE et MUE.ANOMALIE, NOURRITURE.DATE et NOURRITURE.REPAS, INFO_SUP.DATE et INFO_SUP.DETAIL.

    Et je voudrais qu'il y est une ligne pour chaque animal, avec la date max de chaque élément, soit le dernier repas, la dernière mue et la dernière info enregistré pour l'animal avec le repas, l'anomalie, et le detail correspondant a la dernière date. Mais je n'y arrive pas... J'ai utilisé MAX pour les date mais du coup il veux que j'insert les autres colonnes dans un groupe by etc...

    Si quelqu'un pouvais me donner la marche a suivre parce que je sèche vraiment

    Merci d'avance !

  2. #2
    Invité
    Invité(e)
    Par défaut
    qu'est-ce que vous avez déjà fait ?

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2011
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    J'ai tester un peu tout et n'importe quoi...

    Si je tape dans une seul table(MUE par exemple), j'arrive a récupérer la date MAX pour chaque ANIMAL_ID. Mais des que je veux ajouter une colonne supplémentaire, SQL m'oblige a l’insérer dans le 'group by' et du coup je me retrouve avec des ligne en plus...

    Donc déjà dans une table qui contient plusieurs fois chaque ID (qui vient d'une autre table lui), une date associé, et d'autre info, comment je peut récupérer le dernier enregistrement pour chaque ID

    Prenons un exemple simple si vous voulez bien :
    une table qui donne tout les relevés en température de deux piscines
    Table : RELEVE
    Colonne : PISCINE_ID, RELEVE_DATE, RELEVE_TEMP

    ligne1 : pisc1, 18/09/2011, 35
    ligne2 : pisc2, 17/09/2011, 30
    ligne3 : pisc1, 15/09/2011, 29
    ligne4 : pisc2, 15/09/2011, 32
    Quelle requête me permet d'avoir en résultat, deux ligne, une pour chaque piscine, avec la date max pour chacune et la température associé a cette date pour cette piscine ?

    EDIT 19:01 :
    En partant de l'exemple des piscine, j'ai tester ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT PISC_ID, MAX(RELEVE_DATE)
    FROM RELEVE
    GROUP BY PISC_ID
    La pas de soucis j’obtiens une ligne avec l'id pisc1 et une avec pisc2 et pour chacune la date la plus récente correspondante.

    Ensuite j'ajoute la température :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT PISC_ID, MAX(RELEVE_DATE), RELEVE_TEMP
    FROM RELEVE
    GROUP BY PISC_ID, RELEVE_TEMP(Impossible de ne pas le mettre la aussi)
    Et du coup il me ressort les 4 lignes puisque les températures sont différente...

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2011
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    A force de creuser et de chercher, j'ai fini par trouver la solution (pour mon exemple sur les piscine) avec un IN dans la clause where :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT *
    FROM RELEVE
    WHERE RELEVE_DATE IN (SELECT MAX(RELEVE_DATE) 
                          FROM RELEVE
                          GROUP BY PISC_ID)
    Maintenant je tombe sur un autre problème : j'ai trois table cette fois-ci
    table PISCINE : PISC_ID(PK), PISC_LIB
    ligne 1 : 1, Piscine 1
    ligne 2 : 2, Piscine 2

    table RELEVE : PISC_ID(FK, PK1), RLV_DATE(PK2), RLV_TEMP
    ligne1 : 1, 18/09/2011, 35
    ligne2 : 2, 17/09/2011, 30
    ligne3 : 1, 15/09/2011, 29
    ligne4 : 2, 15/09/2011, 32

    table NETTOYAGE : PISC_ID(FK, PK1), NET_DATE(PK2)
    ligne1 : 1, 20/09/2011
    ligne3 : 1, 11/09/2011
    Ma requête donne quelque chose comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT PISC_LIB, RLV_DATE, RLV_TEMP, NET_DATE                              
    FROM PISCINE p JOIN RELEVE r ON p.PISC_ID = r.PISC_ID
                          JOIN NETTOYAGE n ON p.PISC_ID = n.PISC_ID
    WHERE RLV_DATE IN (SELECT MAX(RLV_DATE) 
                                    FROM RELEVE
                                    GROUP BY PISC_ID)
    AND  
    NET_DATE IN (SELECT MAX(NET_DATE) 
                                  FROM NETTOYAGE
                                  GROUP BY PISC_ID)
    Il me ressort donc :
    PISC_LIB | RLV_DATE | RLV_TEMP | NET_DATE
    Piscine 1 | 18/09/2011 | 35 | 20/09/2011
    Et comme la deuxième piscine n'as pas encore été nettoyée, évidement je ne peux pas voir le dernier relevé de température effectué. Je pense qu'il faut utilisé l'union pour ça mais j'ai beau lire l'aide en ligne, je ne vois vraiment pas comment amener ça et j'ai beaucoup de mal à m'en servir.

    Avec deux table, il n'y a pas de soucis j'obtiens ce que je veux avec le IN mais des que j'ajoute la troisième, le problème du cas ou l'un des ID n’apparaît pas dans une des deux table liées vient me gêné

    Merci d'avance à ceux qui porteront de l'attention à ma demande.

  5. #5
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2011
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 118
    Points : 180
    Points
    180
    Par défaut
    Quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT PISC_LIB, RLV_DATE, RLV_TEMP, NET_DATE                              
    FROM PISCINE p 
    INNER JOIN (SELECT MAX(RLV_DATE) AS RLV_DATE, PISC_ID FROM RELEVE GROUP BY PISC_ID) AS r ON p.PISC_ID = r.PISC_ID 
    LEFT JOIN (SELECT MAX(NET_DATE) AS NET_DATE, PISC_ID FROM NETTOYAGE GROUP BY PISC_ID) AS n ON p.PISC_ID = n.PISC_ID

  6. #6
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Une autre solution :

    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
    SELECT 
     P.PISC_LIB,
     REL.RLV_DATE,
     REL. RLV_TEMP,
     (SELECT TOP 1 NET_DATE
      FROM NETTOYAGE AS NET
      WHERE NET.PISC_ID = P.PISC_ID
      ORDER BY NET_DATE DESC) AS NET_DATE
    FROM PISCINE AS P
    CROSS APPLY (
    SELECT 
     TOP 1 RLV_DATE, RLV_TEMP
    FROM RELEVE AS R
    WHERE R.PISC_ID = P.PISC_ID
    ORDER BY RLV_DATE DESC
    ) AS REL;
    ++

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2011
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Je vais tester tout cela, merci beaucoup pour vos réponse

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2011
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par mikedavem Voir le message
    Une autre solution :

    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
    SELECT 
     P.PISC_LIB,
     REL.RLV_DATE,
     REL. RLV_TEMP,
     (SELECT TOP 1 NET_DATE
      FROM NETTOYAGE AS NET
      WHERE NET.PISC_ID = P.PISC_ID
      ORDER BY NET_DATE DESC) AS NET_DATE
    FROM PISCINE AS P
    CROSS APPLY (
    SELECT 
     TOP 1 RLV_DATE, RLV_TEMP
    FROM RELEVE AS R
    WHERE R.PISC_ID = P.PISC_ID
    ORDER BY RLV_DATE DESC
    ) AS REL;
    ++


    Ca fonctionne, a condition qu'il y ai une ligne pour chaque piscine dans la table RLV. Si une piscine n'apparait pas dans cette table, il n'y aura pas de ligne pour le reste... Mais pas mal, ca me fait avancer du coup, je pense que si j'utilise le CROSS APPLY sur la table Piscine, ca devrait marcher


    EDIT 17:56 : Confirmation, en mettant le CROSS APPLY sur la table PISCINE, tout les ligne s'affiche meme si les autre table sont vide, parfait donc

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2011
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par SQLDev Voir le message
    Quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT PISC_LIB, RLV_DATE, RLV_TEMP, NET_DATE                              
    FROM PISCINE p 
    INNER JOIN (SELECT MAX(RLV_DATE) AS RLV_DATE, PISC_ID FROM RELEVE GROUP BY PISC_ID) AS r ON p.PISC_ID = r.PISC_ID 
    LEFT JOIN (SELECT MAX(NET_DATE) AS NET_DATE, PISC_ID FROM NETTOYAGE GROUP BY PISC_ID) AS n ON p.PISC_ID = n.PISC_ID
    Pas encore tester, mais est-ce que le left join va bien m'aligner les lignes comme il faut ?

  10. #10
    Membre habitué
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2011
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 118
    Points : 180
    Points
    180
    Par défaut
    Citation Envoyé par Phoquounet Voir le message
    Pas encore tester, mais est-ce que le left join va bien m'aligner les lignes comme il faut ?
    Oui, c'est l'intérêt du LEFT JOIN, il va juste ajouter les données supplémentaires sur la ligne si elles existent, sinon il affichera juste NULL dans les colonnes ajoutées par le LEFT JOIN.

Discussions similaires

  1. Réponses: 2
    Dernier message: 18/11/2010, 09h54
  2. [SQL SERVER 2008] requête max sur table
    Par mad_martigan dans le forum Développement
    Réponses: 1
    Dernier message: 29/06/2010, 16h31
  3. Requête sur plusieurs tables
    Par sta_schmitt dans le forum Requêtes
    Réponses: 2
    Dernier message: 28/03/2006, 13h54
  4. Requéte sur plusieurs tables
    Par polux23 dans le forum Requêtes
    Réponses: 11
    Dernier message: 23/02/2006, 23h00
  5. Requête sur plusieurs tables
    Par drinkmilk dans le forum Langage SQL
    Réponses: 8
    Dernier message: 11/07/2005, 12h25

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