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 14/04/2011, 22h51   #1
Invité régulier
 
Inscription : décembre 2007
Messages : 30
Détails du profil
Informations forums :
Inscription : décembre 2007
Messages : 30
Points : 5
Points : 5
Par défaut Selection max du dernier enregistrement

Bonjour
Je souhaite sélectionner le dernier enregistrement qui précéde le cas ou pour un ID prof avait une classe égale à "prepa" ( la classe avant qu'on lui affecte la classe prépa)

Ex:
ID Prof Classe Date
Prof1 Seconde 01/09/2009
Prof1 Premiere 01/09/2010
Prof1 Bac 01/01/2011
Prof1 Prepa 01/02/2011
Prof1 Seconde 01/03/2011

résultat: Prof Bac 01/01/2011

Dans oracle, il y a les solutions lead/lag mais dan sql server, avez vous une solution a une telle question ?
merci d'avance
spopo69 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/04/2011, 09h18   #2
Responsable SQL Server

 
Avatar de mikedavem
 
Homme David BARBARIN
Expert SQL Server
Inscription : août 2005
Messages : 3 723
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 723
Points : 6 844
Points : 6 844
Bonjour,

En utilisant la fonction ROW_NUMBER() vous devriez vous en sortir.

Par exemple :

Code :
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
DECLARE @t TABLE
(
 Prof VARCHAR(20),
 Classe VARCHAR(20),
 [Date] DATE
);
 
INSERT @t VALUES ('Prof1', 'Seconde',  '01/09/2009');
INSERT @t VALUES ('Prof1', 'Premiere', '01/09/2010');
INSERT @t VALUES ('Prof1', 'Bac', '01/01/2011');
INSERT @t VALUES ('Prof1', 'Prepa', '01/02/2011');
INSERT @t VALUES ('Prof1', 'Seconde', '01/03/2011');
INSERT @t VALUES ('Prof2', 'Seconde', '01/02/2011');
INSERT @t VALUES ('Prof2', 'Prepa', '01/03/2011');
 
;WITH CTE
AS
(
 SELECT ROW_NUMBER() OVER(PARTITION BY Prof ORDER BY Date DESC) AS num,*
 FROM @t
)
SELECT 
 C2.Prof,
 C2.Classe, 
 C2.[Date] 
FROM CTE AS C
INNER JOIN CTE AS C2
 ON C.num = C2.num - 1
  AND C.Prof = C2.Prof
WHERE C.Classe = 'Prepa'
++
mikedavem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/04/2011, 14h19   #3
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Bonjour,


Une autre solution, qui pourra etre meilleure ou moins bonne en fonction de vos données et de vos index :

Code SQL :
1
2
3
4
5
6
7
8
9
10
11
12
13
 
 
 
 SELECT t1.Prof, T.Classe, T.Dte
 FROM @t t1
 OUTER APPLY (
	SELECT TOP(1) Classe, Dte
	FROM @t t2
	WHERE T2.Prof = T1.Prof
	AND T2.Dte < T1.Dte
	ORDER BY Dte DESC
) T
WHERE t1.Classe = 'Prepa'
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/04/2011, 18h58   #4
Invité régulier
 
Inscription : décembre 2007
Messages : 30
Détails du profil
Informations forums :
Inscription : décembre 2007
Messages : 30
Points : 5
Points : 5
J ai du mal à exécuter cette requête car je dispose de quatre jointures.
Ci-dessous le code sql généré quand je liste les trois champs: IdProf, Classe et DateFin

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT
  T_Prof.IdProf,
  T_Classe_histo.Classe,
  T_Date.DateFin
FROM
  Dte     T_Date,
  Classe  T_Classe_histo,
  Classe  T_Classe,
  Prof    T_Prof
WHERE
  ( T_Classe.IdEle=T_Prof.IdEle  )
  AND  ( T_Classe_histo.IdEle=T_Date.IdShem  )
  AND  ( T_Date.IDPI2=T_Prof.IDPI  )
Merci
spopo69 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/04/2011, 09h37   #5
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 667
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

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

Informations forums :
Inscription : janvier 2005
Messages : 4 667
Points : 8 715
Points : 8 715
Bonjour,

Vous remarquerez que l'alias T_Classe de la tale Classe est inutile, puisqu'il n'est ni dans les prédicats de jointure, ni dans la liste des colonnes du SELECT.

Donc on peut réécrire la requête comme suit, à la norme, avec la CTE

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
;WITH
	CTE AS
	(
		SELECT		T_Prof.IdProf
				, T_Classe_histo.Classe
				, T_Date.DateFin
				, ROW_NUMBER() OVER(PARTITION BY IdProf ORDER BY DateFin DESC) AS num
		FROM		dbo.Dte AS T_Date
		INNER JOIN	dbo.Classe AS T_Classe_histo
					ON T_Classe_histo.IdEle = T_Date.IdShem
		INNER JOIN	dbo.Prof AS T_Prof
					ON T_Classe.IdEle = T_Prof.IdEle
					AND T_Date.IDPI2 = T_Prof.IDPI
	)
SELECT		C2.IdProf
		, C2.Classe
		, C2.DateFin 
FROM		CTE AS C
INNER JOIN	CTE AS C2
			ON C.num = C2.num - 1
			AND C.IdProf = C2.IdProf
WHERE		C.Classe = 'Prepa'
@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/04/2011, 22h37   #6
Invité régulier
 
Inscription : décembre 2007
Messages : 30
Détails du profil
Informations forums :
Inscription : décembre 2007
Messages : 30
Points : 5
Points : 5
merci
spopo69 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 03h03.


 
 
 
 
Partenaires

Hébergement Web