Bonjour,
Je me posais une question aujourd'hui puisque je faisais face à un problème que je ne savais pas comment résoudre. Supposons que nous avons cette table qui fait référence à une autre (peu importe l'autre) :
Admettons que je souhaite sélectionner une ligne par client, la ligne qui contient le dateDebut le plus récent. Instinctivement, je ferais cette requête, en supposant que mon SGBDR va sélectionner les autres colonnes par lui-même :
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 -- Table CREATE TABLE commandes ( id serial, idClient integer, libelle varchar(50), dateDebut date, dateFin date, CONSTRAINT pk_id_idClient PRIMARY KEY (id, idClient), FOREIGN KEY (idClient) REFERENCES clients (id) ); -- Jeu d'essai INSERT INTO commandes (idClient, libelle, dateDebut, dateFin) VALUES (1, 'A43F22G', '2010-05-17', '2010-06-17'); INSERT INTO commandes (idClient, libelle, dateDebut, dateFin) VALUES (1, 'B66FA27', '2010-04-17', '2010-05-17'); INSERT INTO commandes (idClient, libelle, dateDebut, dateFin) VALUES (2, '65F787A', '2010-05-08', '2010-06-08'); INSERT INTO commandes (idClient, libelle, dateDebut, dateFin) VALUES (2, '764AB1F', '2010-06-08', '2010-07-08'); INSERT INTO commandes (idClient, libelle, dateDebut, dateFin) VALUES (3, '12ABC5E', '2010-05-10', '2010-06-10'); INSERT INTO commandes (idClient, libelle, dateDebut, dateFin) VALUES (4, 'FD389A0', '2010-04-20', '2010-05-20');
Mais ça ne marche pas, le SGBDR me dit que je dois utiliser id, libelle et dateFin dans le GROUP BY ou dans une fonction d'agrégat. Je souhaiterais que ma requête affiche ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 SELECT id, idClient, libelle, MAX(dateDebut), dateFin FROM commandes GROUP BY idClient;
J'ai beau essayé, je n'ai pas trouvé comment faire. J'ai pensé à utiliser plusieurs sous-requêtes, mais je ne pense pas que cette solution soit appropriée (ça ferait une sous-requête par colonne, ça doit devenir vite très lourd). Est-ce que quelqu'un pourrait éclairer ma lanterne ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 id | idclient | libelle | datedebut | datefin ----+----------+---------+------------+------------ 1 | 1 | A43F22G | 2010-05-17 | 2010-06-17 4 | 2 | 764AB1F | 2010-06-08 | 2010-07-08 5 | 3 | 12ABC5E | 2010-05-10 | 2010-06-10 6 | 4 | FD389A0 | 2010-04-20 | 2010-05-20
Merci d'avance,
Jihnn
P.S. Je suis sous PostgreSQL 8.4.3, mais je souhaiterais avoir une requête la plus générale possible (qui pourrait aussi fonctionner sous MySQL par exemple).
Edit: J'ai pensé à un truc après avoir posté :
Est-ce la meilleure façon ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 SELECT id, idClient, libelle, dateDebut, dateFin FROM commandes WHERE dateDebut IN ( SELECT MAX(dateDebut) FROM commandes GROUP BY idClient ) ORDER BY idClient;
Partager