2010-03-28 7 views
3

Pourquoi les deux requêtes ci-dessous renvoient le doublon member_id et pas le troisième?Pourquoi mon mysql DISTINCT ne fonctionne pas?

J'ai besoin de la deuxième requête pour travailler avec distinct. Chaque fois que je lance un GROUP BY, cette requête est incroyablement lente et le résultat ne retourne pas la même valeur que la valeur distincte (la valeur est erronée).

SELECT member_id, id 
FROM (SELECT * FROM table1 ORDER BY created_at desc) as u 
LIMIT 5 

+-----------+--------+ 
| member_id | id  | 
+-----------+--------+ 
|  11333 | 313095 | 
| 141831 | 313094 | 
| 141831 | 313093 | 
|  12013 | 313092 | 
|  60821 | 313091 | 
+-----------+--------+ 

SELECT distinct member_id, id 
FROM (SELECT * FROM table1 ORDER BY created_at desc) as u 
LIMIT 5 

+-----------+--------+ 
| member_id | id  | 
+-----------+--------+ 
|  11333 | 313095 | 
| 141831 | 313094 | 
| 141831 | 313093 | 
|  12013 | 313092 | 
|  60821 | 313091 | 
+-----------+--------+ 

SELECT distinct member_id 
    FROM (SELECT * FROM table1 ORDER BY created_at desc) as u 
    LIMIT 5 

+-----------+ 
| member_id | 
+-----------+ 
|  11333 | 
| 141831 | 
|  12013 | 
|  60821 | 
|  64980 | 
+-----------+ 

mon échantillon de table

CREATE TABLE `table1` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `member_id` int(11) NOT NULL, 
    `s_type_id` int(11) NOT NULL, 
    `created_at` datetime DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `s_FI_1` (`member_id`), 
    KEY `s_FI_2` (`s_type_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=313096 DEFAULT CHARSET=utf8; 
+0

Pourquoi n'utilisez-vous pas une syntaxe similaire? SELECT distinct member_id FROM table1 ORDER BY created_at desc LIMIT 5 – Eineki

+0

la parenthèse donne la priorité à la commande, et j'ai besoin de récupérer aussi la colonne id. – belaz

+0

pour être clair, j'ai besoin de récupérer {member_id, id} qui est la dernière entrée 5 et chaque ligne doit avoir le {member_id} unique. – belaz

Répondre

2

cela fonctionne, son sale (pas d'index, aucune clé, table temporaire ...) mais cela fonctionne,

SELECT member_id,id 
FROM (SELECT member_id,id, created_at FROM table1 ORDER BY created_at desc) as u 
group by member_id ORDER BY created_at desc LIMIT 5; 
1

Dans la première requête, il n'y a pas mot-clé distinct. Dans la deuxième requête, il sélectionne des lignes distinctes. ID membre non distinct. Dans la troisième requête, il n'y a qu'un identifiant d'élément, de sorte qu'il consiste à sélectionner les membres distincts ids

1

SELECT member_id distinct, id à partir de (SELECT * FROM Table1 ORDER BY created_at desc) sous la forme u LIMIT 5

member_id n'est pas unique. Cela fait que la requête affiche plus de lignes ...

+0

PRIMARY KEY ('id') – belaz

+0

Oups, signifiait member_id. Corrigée. Mais même si member_id où une clé primaire aussi, alors Table1 pourrait être une vue regroupant les deux champs;) – Ropstah

17

DISTINCT est un mot-clé que vous ne pouvez appliquer que sur SELECT, et non sur un seul champ. Il s'assure que la base de données ne renvoie pas deux lignes identiques. C'est pourquoi votre deuxième requête avec DISTINCT renvoie une seule fois chacune member_id tandis que votre première renvoie deux fois. Dans son ensemble de résultats, chaque ligne est en effet unique, même si vous pouvez obtenir plusieurs fois la même member_id.

+2

Peut-être qu'un jour les gens commenteront quand ils downvote ... – zneak

+0

Je vais upvote à la place - devrais-je encore commenter :) - pour un point de pertinence, la réponse de zneak est sur place. – Lee

+0

Je ne downvote pas; Je préfère commenter. –

0

Créer les indices suivants:

CREATE INDEX ix_table1_createdat ON table1 (created_at); 
CREATE INDEX ix_table1_memberid_createdat ON table1 (member_id, created_at); 

et utilisez cette requête:

SELECT t1i.* 
FROM (
     SELECT DISTINCT member_id 
     FROM table1 tdi 
     ORDER BY 
       created_at DESC 
     LIMIT 5 
     ) t1d 
JOIN table1 t1i 
ON  t1i.id = 
     (
     SELECT t1o.id 
     FROM table1 t1o 
     WHERE t1o.member_id = t1d.member_id 
     ORDER BY 
       t1o.member_id DESC, t1o.created_at DESC 
     LIMIT 1 
     ) 
Questions connexes