Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours 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 05/06/2011, 16h33   #1
Invité de passage
 
Inscription : juin 2007
Messages : 7
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 7
Points : 2
Points : 2
Par défaut DISTINCT sur une seule colonne

Bonjour,

Tout d'abord je tiens à indiquer que je sais parfaitement que DISTINCT ne peut être utilisé ici mais je ne trouvais pas de titre pour mon problème.

Voici mon problème :

J'ai une table comportant les colonnes suivantes : pseudo, point_id, date, note.
Je souhaiterais obtenir la dernière personne étant passée par chaque point ainsi que la date de son passage et la note qu'il a laissée.

Par exemple si ma table contient ces valeurs :

Code :
1
2
3
4
5
6
7
8
 
pseudo	point_id	date			note
toto	1		2011-04-03
tata	1		2011-04-05
titi	1		2011-04-01
toto	2		2011-04-04
toto	3		2011-04-02
tata	3		2011-04-03
je souhaiterais obtenir :

Code :
1
2
3
4
5
 
pseudo	point_id	date			note
tata	1		2011-04-05
toto	2		2011-04-04
tata	3		2011-04-03
Merci d'avance pour votre aide.
Geek87 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 16h50   #2
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
bonjour voici une possibilité :

Code sql :
1
2
3
4
5
6
7
8
9
   SELECT Table1.Point_Id,
               Table1.DATE,
               Table1.Pseudo,
               Table1.Note
          FROM (SELECT Table1.Point_Id,
                       MAX(Table1.DATE)
                  FROM Table1
                  GROUP BY Table1.Point_Id) AS Selection
            INNER JOIN Table1 ON (Selection.Point_Id = Table1.Point_Id AND Selection.DATE = Table1.DATE)

note 1 : Il faut créer un index descendant sur la colonne "date"

Note 2 : C'est une TRES mauvaise idée de donner un mot réservé à un nom de colonne
dehorter olivier est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 05/06/2011, 21h01   #3
Invité de passage
 
Inscription : juin 2007
Messages : 7
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 7
Points : 2
Points : 2
Merci pour la réponse.

J'ai également trouvé ceci en cherchant et j'aurais aimé savoir s'il y avait une solution meilleure que l'autre ou pas ?

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
SELECT
	*
FROM
	Table1
WHERE
	Date =
	(
		SELECT
			MAX(Date)
		FROM
			Table1 AS Selection
		WHERE
			Table1.Point_id = Selection.Point_id
	)
Pour la colonne date je m'en suis rendu compte au moment de faire cette requête mais j'ai déjà du code qui en dépend donc je modifierai tout à la fin si j'ai le temps. Je ne sais pas à quoi je pensais quand j'ai appelé cette colonne comme ça…
Geek87 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 05/06/2011, 22h02   #4
Membre habitué
 
Avatar de tfc3146
 
Homme Robert Labrousse
Développeur décisionnel
Inscription : février 2009
Messages : 79
Détails du profil
Informations personnelles :
Nom : Homme Robert Labrousse
Localisation : France

Informations professionnelles :
Activité : Développeur décisionnel
Secteur : Boutique - Magasin

Informations forums :
Inscription : février 2009
Messages : 79
Points : 134
Points : 134
Bonsoir,

Geek87 votre requête est plus simple et plus performante (pas de GROUP BY), donc à utiliser.
__________________
Citation:
C'est en faisant n'importe quoi qu'on devient n'importe qui
Si un message vous a aidé, n'hésitez pas à mettre +1
tfc3146 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 05/06/2011, 22h33   #5
Invité de passage
 
Inscription : juin 2007
Messages : 7
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 7
Points : 2
Points : 2
Merci pour vos réponses à tous les deux !

Je marque résolu.
Geek87 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 23h34   #6
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
Bonjour,

Afin d'éviter plusieurs scannages de tables / index vous pourriez aussi utilisez une fonctions de fenêtrages :

Code :
1
2
3
4
5
6
7
8
 
WITH tmp AS (
SELECT pseudo, point_id, Date, note, dense_rank() over(partition BY point_id ORDER BY Date DESC) AS rnk
FROM Table1)
 
SELECT pseudo, point_id, Date, note
FROM tmp
WHERE rnk = 1;
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 08h48   #7
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
En effet, elle est plus rapide. Mais elle ne fournit pas les mêmes résultats
Pour la sous requête, c'est ok.
Mais avec la requête principale, elle renvoie toutes les infos pour les dates considérées (donc il peut avoir plusieurs lignes pour un même "Point_Id").

Citation:
Envoyé par Geek87 Voir le message
Merci pour la réponse.

J'ai également trouvé ceci en cherchant et j'aurais aimé savoir s'il y avait une solution meilleure que l'autre ou pas ?

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
SELECT
	*
FROM
	Table1
WHERE
	Date =
	(
		SELECT
			MAX(Date)
		FROM
			Table1 AS Selection
		WHERE
			Table1.Point_id = Selection.Point_id
	)
Pour la colonne date je m'en suis rendu compte au moment de faire cette requête mais j'ai déjà du code qui en dépend donc je modifierai tout à la fin si j'ai le temps. Je ne sais pas à quoi je pensais quand j'ai appelé cette colonne comme ça…
dehorter olivier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 09h48   #8
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
Citation:
Envoyé par dehorter olivier Voir le message
En effet, elle est plus rapide. Mais elle ne fournit pas les mêmes résultats
Pour la sous requête, c'est ok.
Mais avec la requête principale, elle renvoie toutes les infos pour les dates considérées (donc il peut avoir plusieurs lignes pour un même "Point_Id").
au vu de la jointure "Table1.Point_id = Selection.Point_id" je penses que sa requête est bonne, vu que la date max considérée pour une ligne ne le sera que pour le point_id en question.
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 09h55   #9
Invité de passage
 
Inscription : juin 2007
Messages : 7
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 7
Points : 2
Points : 2
Oui je viens de vérifier j'ai bien les mêmes résultats avec les deux requêtes. Je n'ai pas compris pourquoi cela ne devrait pas être le cas ?
Geek87 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 10h45   #10
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837


mea culpa, c'est ma faute

oui cela marche
dehorter olivier 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 18h48.


 
 
 
 
Partenaires

Hébergement Web