Rêquete d'un débutant

Rêquete d'un débutant - SQL/NoSQL - Programmation

Marsh Posté le 26-11-2006 à 20:55:02    

Bonjour,
 
je suis débutant en base de donnée et je voulais savoir comment fussionner ces deux requêtes en MySQL

Code :
  1. SELECT * FROM log ORDER BY date DESC
  2. SELECT * FROM log GROUP BY ip


 
en gros j'aimerais afficher les tuples correspondant à l'adresse ip la plus récente sans doublons
 
Je l'ai presque en faisant  

Code :
  1. SELECT DISTINCT ip FROM log ORDER BY date DESC


mais je voudrais lire tous les champs de ma table
 
Comment on fait aussi pour sélectionner toutes les colonnes de sa table sauf une ?


Message édité par joe451 le 26-11-2006 à 20:59:25
Reply

Marsh Posté le 26-11-2006 à 20:55:02   

Reply

Marsh Posté le 26-11-2006 à 23:12:02    

cf. commande SQL `GROUP BY`
Par contre, il me semble qu'il fasse spécifier les champs voulu et non un *

Reply

Marsh Posté le 26-11-2006 à 23:19:31    

Je ne sais si j'ai été clair alors voilà ce que je désirerais
(j'ai remplacé l'adresse ip par un nom. C'est plus simple)
 
Afficher la table sans doublons classée par date
 
En gros,
Transformer cette table
 

Code :
  1. id   | Nom        | Date_de_visite
  2. 1    | Paul       | 10-01-2000
  3. 2    | Pierre     | 05-01-2000
  4. 3    | Jacques    | 04-01-2000
  5. 4    | Jean       | 05-01-2000
  6. 5    | Paul       | 02-01-2000
  7. 6    | Pierre     | 07-01-2000
  8. 7    | Paul       | 12-01-2000


 
en celle là en éliminant les doublons les plus vieux
 

Code :
  1. id   | Nom        | Date_de_visite
  2. 7    | Paul       | 12-01-2000
  3. 6    | Pierre     | 07-01-2000
  4. 4    | Jean       | 05-01-2000
  5. 3    | Jacques    | 04-01-2000
  6. 5    | Paul       | 02-01-2000


 
Existe-t-il une facon simple de faire cela ?

Reply

Marsh Posté le 26-11-2006 à 23:21:34    

Master p a écrit :

cf. commande SQL `GROUP BY`
Par contre, il me semble qu'il fasse spécifier les champs voulu et non un *


oui c'est bien mon soucis. Je voudrais un *. C'est possible avec une requête imbriquée ?

Message cité 1 fois
Message édité par joe451 le 26-11-2006 à 23:26:13
Reply

Marsh Posté le 26-11-2006 à 23:32:34    

joe451 a écrit :

oui c'est bien mon soucis. Je voudrais un *. C'est possible avec une requête imbriquée ?


Liste tes champs dans le SELECT, au lieu du * :

Code :
  1. SELECT id,Nom,Date_de_visite
  2. FROM `kloltksbye`
  3. GROUP BY (id)
  4. ORDER BY Date_de_visite DESC


Mais, en fait, ça marche aussi avec un * [:dawao]

Reply

Marsh Posté le 26-11-2006 à 23:37:06    

Master p a écrit :

Liste tes champs dans le SELECT, au lieu du * :

Code :
  1. SELECT id,Nom,Date_de_visite
  2. FROM `kloltksbye`
  3. GROUP BY (id)
  4. ORDER BY Date_de_visite DESC


Mais, en fait, ça marche aussi avec un * [:dawao]


 
euh ce serait plutot GROUP BY Nom , non ?
Mais j'ai même un problème...

Message cité 1 fois
Message édité par joe451 le 26-11-2006 à 23:38:13
Reply

Marsh Posté le 26-11-2006 à 23:41:33    

joe451 a écrit :

euh ce serait plutot GROUP BY Nom , non ?
Mais j'ai même un problème...

Je t'ai donné un mode d'emploi, pas la solution de ton exercice [:dawak]

joe451 a écrit :

Existe-t-il une facon simple de faire cela ?

Oui, et c'est très simple par le biais d'un GROUP BY

Reply

Marsh Posté le 27-11-2006 à 00:16:22    

Master p a écrit :

Je t'ai donné un mode d'emploi, pas la solution de ton exercice [:dawak]
Oui, et c'est très simple par le biais d'un GROUP BY


 
Ca marche pas avec
SELECT *  
FROM `table`  
GROUP BY `Nom`  
ORDER BY `Date_de_visite` ASC
 
si par exemple je rajoute  
id   |Nom      |Date_de_visite
8    |Gérard   |12-01-2000 2000-01-08 00:00:00
9    |Gérard   |12-01-2000 2000-01-05 00:00:00
10   |Gérard   |12-01-2000 2000-01-06 00:00:00
 
J'aurais toujours le n°8 en réponse alors que je voudrais le 9 pour `Date_de_visite` ASC
J'ai le 8 pour `Date_de_visite` DESC mais c'est un coup de chance. C'est parce que c'est le premier si on classe par id

Reply

Marsh Posté le 27-11-2006 à 00:28:40    

Pour ceux que ca interesse, voici la table

Code :
  1. --
  2. -- Structure de la table `table`
  3. --
  4. CREATE TABLE `table` (
  5.   `id` int(4) NOT NULL auto_increment,
  6.   `Nom` varchar(8) collate latin1_general_ci NOT NULL,
  7.   `Date_de_visite` datetime NOT NULL,
  8.   PRIMARY KEY  (`id`)
  9. ) ENGINE=MyISAM AUTO_INCREMENT=13 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=13 ;
  10. --
  11. -- Contenu de la table `table`
  12. --
  13. INSERT INTO `table` VALUES (1, 'Paul', '2000-01-10 00:00:00');
  14. INSERT INTO `table` VALUES (2, 'Pierre', '2000-01-05 00:00:00');
  15. INSERT INTO `table` VALUES (3, 'Jacques', '2000-01-04 00:00:00');
  16. INSERT INTO `table` VALUES (4, 'Jean', '2000-01-05 00:00:00');
  17. INSERT INTO `table` VALUES (5, 'Paul', '2000-01-02 00:00:00');
  18. INSERT INTO `table` VALUES (6, 'Pierre', '2000-01-07 00:00:00');
  19. INSERT INTO `table` VALUES (7, 'Paul', '2000-01-12 00:00:00');
  20. INSERT INTO `table` VALUES (8, 'Gérard', '2000-01-08 00:00:00');
  21. INSERT INTO `table` VALUES (9, 'Gérard', '2000-01-05 00:00:00');
  22. INSERT INTO `table` VALUES (10, 'Gérard', '2000-01-06 00:00:00');
  23. INSERT INTO `table` VALUES (11, 'Gérard', '2000-01-09 00:00:00');


et voici ce que je voudrais en réponse

Code :
  1. id   | Nom       | Date_de_visite
  2. 7    | Paul      | 2000-01-12 00:00:00
  3. 11   | Gérard    | 2000-01-09 00:00:00
  4. 6    | Pierre    | 2000-01-07 00:00:00
  5. 4    | Jean      | 2000-01-05 00:00:00
  6. 3    | Jacques   | 2000-01-04 00:00:00


Message édité par joe451 le 27-11-2006 à 01:25:14
Reply

Marsh Posté le 27-11-2006 à 00:57:20    

:/ la prochaine fois, j'évite de poster sans réfléchir.

Code :
  1. SELECT Nom, Min(`Date_de_visite`)
  2. FROM `table`
  3. GROUP BY `Nom`

Fig 1. : Teh mighty GROUP BY comamnd

Reply

Marsh Posté le 27-11-2006 à 00:57:20   

Reply

Marsh Posté le 27-11-2006 à 00:59:01    

Pour info, cette utilisation des GROUP BY fonctionne aussi avec la commande HAVING() (peut-être moins standart, j'en sais rien [:spamafote])

Reply

Marsh Posté le 27-11-2006 à 01:31:59    

Master p a écrit :

:/ la prochaine fois, j'évite de poster sans réfléchir.

Code :
  1. SELECT Nom, Min(`Date_de_visite`)
  2. FROM `table`
  3. GROUP BY `Nom`

Fig 1. : Teh mighty GROUP BY comamnd


 
Si je fais cela

Code :
  1. SELECT id,Nom, Max( `Date_de_visite` ) AS Date_de_visite
  2. FROM `table`
  3. GROUP BY `Nom`
  4. ORDER BY `Date_de_visite` DESC


 
j'ai ca en réponse

Code :
  1. id  Nom      Date_de_visite
  2. 1   Paul     2000-01-12 00:00:00
  3. 8   Gérard   2000-01-09 00:00:00
  4. 2   Pierre   2000-01-07 00:00:00
  5. 4   Jean     2000-01-05 00:00:00
  6. 3   Jacques  2000-01-04 00:00:00

 
C'est presque bon sauf que je n'ai pas les bons identifiants mais on se rapproche je le sens...
Bon je vais dormir lol
Merci de ton aide Master p


Message édité par joe451 le 27-11-2006 à 01:36:00
Reply

Marsh Posté le 27-11-2006 à 01:50:25    

Dans ce cas là, c'est donc GROUP BY + HAVING
Il y a de la doc dispo sur le net, te gêne pas [:ootransparent]

Message cité 1 fois
Message édité par Master p le 27-11-2006 à 01:50:38
Reply

Marsh Posté le 27-11-2006 à 18:33:28    

Master p a écrit :

Dans ce cas là, c'est donc GROUP BY + HAVING
Il y a de la doc dispo sur le net, te gêne pas [:ootransparent]


 :heink:  euh je ne vois pas quelle condition mettre dans le HAVING pour avoir les bons "id"...


Message édité par joe451 le 27-11-2006 à 20:09:26
Reply

Marsh Posté le 27-11-2006 à 21:17:54    

pas top le group by pour fusionner des requêtes. Le group by s'utilise plutot avec des fonctions tel que COUNT, MAX, MIN, SUM, etc...
 
je pense qu'ici un UNION est bcp plus adéquat
 
SELECT ...
FROM ...
WHERE ...
UNION
SELECT ...
FROM ...
WHERE ...
 
Attention que dans la clause SELECT, il faut le même nombre de champ et que ceux ci soit de mêmes types

Reply

Marsh Posté le 27-11-2006 à 22:02:23    

Bon je cherche mais je galère. Personne n'a d'idées ?

Reply

Marsh Posté le 27-11-2006 à 22:05:39    

Bon, bah je crois que j'était trop optimiste pour le GROUP BY + HAVING (surtout que je voulais faire l'économie d'une sous-requête).
Solution Barbare : Sous-requête pour trouver le max et retrouver l'id lui appartenant dans la table `table` :

Code :
  1. SELECT a.id, a.Nom, a.Date_de_visite
  2. FROM `table` as a,
  3.   (SELECT Nom as Nom2, MAX(Date_de_visite) as date2 FROM `table` GROUP BY Nom) as b
  4. WHERE a.Nom=b.Nom2 and a.Date_de_visite = b.date2


Mais j'aurais voulu une solution plus propre...
Désolé pour le mauvais aiguillage ...

Reply

Marsh Posté le 27-11-2006 à 22:40:33    

Oh ! :ouch:  Ca marche ! merci Master p.
C'est vrai que j'ai un peu galéré avec le group by+having en me disant que c'était probablement parce que je débutais... Je pensais aussi y arriver par une requête simple mais là j'ai ce que veux même si la requête est un peu plus longue. Je ne savais même pas que l'on pouvait mettre ce genre de trucs dans le FROM mais c'est bon, ca fonctionne

Reply

Marsh Posté le 28-11-2006 à 19:09:17    

Master p a écrit :

Bon, bah je crois que j'était trop optimiste pour le GROUP BY + HAVING (surtout que je voulais faire l'économie d'une sous-requête).
Solution Barbare : Sous-requête pour trouver le max et retrouver l'id lui appartenant dans la table `table` :

Code :
  1. SELECT a.id, a.Nom, a.Date_de_visite
  2. FROM `table` as a,
  3.   (SELECT Nom as Nom2, MAX(Date_de_visite) as date2 FROM `table` GROUP BY Nom) as b
  4. WHERE a.Nom=b.Nom2 and a.Date_de_visite = b.date2


Mais j'aurais voulu une solution plus propre...
Désolé pour le mauvais aiguillage ...


 
Tu fais une sous-requête dans tous les cas ...
Il faut une requête pour récupérer l'enregistrement le plus récent, et une autre pour les détails correspondants.
 
SELECT a.id, a.Nom, a.Date_de_visite
FROM `table` as a
WHERE a.Date_de_visite =
(SELECT MAX(Date_de_visite) FROM `table` WHERE nom = a.Nom);

Reply

Marsh Posté le 28-11-2006 à 21:00:26    

Pas forcément.
On peut s'en tirer sans, mais ça n'est pas du tout meilleur niveau perfs.
En effet, le HAVING est particulièrement lent.
C'est surtout utile pour ceux qui ont MySQL < 4.1 en somme...
 


SELECT  
    a.id,  
    a.Nom,  
    a.Date_de_visite,
    max(b.Date_de_visite)
FROM `table` as a
inner join `table` as b on b.nom = a.nom
group by a.Nom, a.Date_de_visite
HAVING a.Date_de_visite = max(b.Date_de_visite);


Message édité par MagicBuzz le 28-11-2006 à 21:01:26
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed