Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 24/09/2011, 14h57   #1
Invité de passage
 
Homme Ronan
Développeur informatique
Inscription : septembre 2011
Messages : 12
Détails du profil
Informations personnelles :
Nom : Homme Ronan
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : septembre 2011
Messages : 12
Points : 4
Points : 4
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 !
Phoquounet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/09/2011, 17h11   #2
Expert Confirmé
 
Avatar de 7gyY9w1ZY6ySRgPeaefZ
 
Homme
dba
Inscription : juillet 2007
Messages : 2 520
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Canada

Informations professionnelles :
Activité : dba

Informations forums :
Inscription : juillet 2007
Messages : 2 520
Points : 3 968
Points : 3 968
qu'est-ce que vous avez déjà fait ?
__________________
les règles du forum - mode d'emploi du forum
Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs.
(Rappel : "ça ne marche pas" n'est pas un message d'erreur)
JE NE RÉPONDS PAS aux questions techniques par message privé.
Écrire en français sur un forum est une marque minimale de respect.
7gyY9w1ZY6ySRgPeaefZ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/09/2011, 18h51   #3
Invité de passage
 
Homme Ronan
Développeur informatique
Inscription : septembre 2011
Messages : 12
Détails du profil
Informations personnelles :
Nom : Homme Ronan
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : septembre 2011
Messages : 12
Points : 4
Points : 4
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
Citation:
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 :
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 :
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...
Phoquounet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/09/2011, 23h56   #4
Invité de passage
 
Homme Ronan
Développeur informatique
Inscription : septembre 2011
Messages : 12
Détails du profil
Informations personnelles :
Nom : Homme Ronan
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : septembre 2011
Messages : 12
Points : 4
Points : 4
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 :
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
Citation:
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 :
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 :
Citation:
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.
Phoquounet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/09/2011, 12h50   #5
Nouveau Membre du Club
 
Homme Christophe
Administrateur de base de données
Inscription : juin 2011
Messages : 29
Détails du profil
Informations personnelles :
Nom : Homme Christophe
Localisation : France

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

Informations forums :
Inscription : juin 2011
Messages : 29
Points : 39
Points : 39
Quelque chose comme ça :
Code :
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
SQLDev est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/10/2011, 09h29   #6
Responsable SQL Server

 
Avatar de mikedavem
 
Homme David BARBARIN
Expert SQL Server
Inscription : août 2005
Messages : 3 724
Détails du profil
Informations personnelles :
Nom : Homme David BARBARIN
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Expert SQL Server
Secteur : Conseil

Informations forums :
Inscription : août 2005
Messages : 3 724
Points : 6 848
Points : 6 848
Une autre solution :

Code :
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;
++
mikedavem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/10/2011, 16h35   #7
Invité de passage
 
Homme Ronan
Développeur informatique
Inscription : septembre 2011
Messages : 12
Détails du profil
Informations personnelles :
Nom : Homme Ronan
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : septembre 2011
Messages : 12
Points : 4
Points : 4
Je vais tester tout cela, merci beaucoup pour vos réponse
Phoquounet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/10/2011, 17h46   #8
Invité de passage
 
Homme Ronan
Développeur informatique
Inscription : septembre 2011
Messages : 12
Détails du profil
Informations personnelles :
Nom : Homme Ronan
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : septembre 2011
Messages : 12
Points : 4
Points : 4
Citation:
Envoyé par mikedavem Voir le message
Une autre solution :

Code :
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
Phoquounet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/10/2011, 17h47   #9
Invité de passage
 
Homme Ronan
Développeur informatique
Inscription : septembre 2011
Messages : 12
Détails du profil
Informations personnelles :
Nom : Homme Ronan
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : septembre 2011
Messages : 12
Points : 4
Points : 4
Citation:
Envoyé par SQLDev Voir le message
Quelque chose comme ça :
Code :
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 ?
Phoquounet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/10/2011, 10h10   #10
Nouveau Membre du Club
 
Homme Christophe
Administrateur de base de données
Inscription : juin 2011
Messages : 29
Détails du profil
Informations personnelles :
Nom : Homme Christophe
Localisation : France

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

Informations forums :
Inscription : juin 2011
Messages : 29
Points : 39
Points : 39
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.
SQLDev est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 17h51.


 
 
 
 
Partenaires

Hébergement Web