2010-08-08 4 views
2

J'ai une table avec des données et je veux sélectionner les données les plus récentes pour chaque type ...MySQL Query, optimisation des sous-requêtes, SELECT, REJOIGNEZ

Tableau:

+----+------+------+---------------------+ 
| ID | data | type | date    | 
+----+------+------+---------------------+ 
| 1 | just | 2 | 2010-08-07 14:24:48 | 
| 2 | some | 2 | 2010-08-07 18:07:32 | 
| 3 | data | 9 | 2010-08-06 02:52:17 | 
| 4 | abcd | 1 | 2010-08-08 17:23:22 | 
| 5 | efg1 | 5 | 2010-07-10 21:36:55 | 
| 6 | c123 | 5 | 2010-07-10 20:44:36 | 
| 7 | bbey | 12 | 2010-08-09 09:01:26 | 
+----+------+------+---------------------+ 

Actuellement, je suis en utilisant de simples et sous-requête ressemble à tout fonctionne

SELECT `data`,`type`,`date` 
FROM `table1` 
WHERE `date` = (
        SELECT MAX(`date`) 
        FROM `table1` AS tbl2 
        WHERE tbl2.`type` = `table1`.`type` 
       ) 
GROUP BY `type` 
ORDER BY `type`,`date` 

Résultat:

+------+------+---------------------+ 
| data | type | date    | 
+------+------+---------------------+ 
| abcd | 1 | 2010-08-08 17:23:22 | 
| some | 2 | 2010-08-07 18:07:32 | 
| efg1 | 5 | 2010-07-10 21:36:55 | 
| data | 9 | 2010-08-06 02:52:17 | 
| bbey | 12 | 2010-08-09 09:01:26 | 
+------+------+---------------------+ 

Ma question est est-il une meilleure façon de faire, une certaine optimisation, amélioration ou peut-être il est possible de faire rejoindre?

Répondre

2

Vous utilisez un sous-requête corrélée. La sous-requête dépend de la requête externe et, par conséquent, elle doit être exécutée une fois pour chaque ligne de la requête externe.

En général, cela peut être amélioré en utilisant votre sous-requête au lieu table dérivée. Depuis une sous-requête comme une table dérivée n'est pas corrélée à la requête externe, cette solution est considérée comme plus évolutive:

SELECT t1.`data`, t1.`type`, t1.`date` 
FROM  `table1` t1 
JOIN  (
       SELECT MAX(`date`) `max_date`, `type` 
       FROM  `table1` 
       GROUP BY `type` 
     ) der_t ON (der_t.`max_date` = t1.`date` AND der_t.`type` = t1.`type`) 
GROUP BY t1.`type` 
ORDER BY t1.`type`, t1.`date`; 

Cas de test:

CREATE TABLE table1 (id int, data varchar(10), type int, date datetime); 

INSERT INTO table1 VALUES (1, 'just', 2, '2010-08-07 14:24:48'); 
INSERT INTO table1 VALUES (2, 'some', 2, '2010-08-07 18:07:32'); 
INSERT INTO table1 VALUES (3, 'data', 9, '2010-08-06 02:52:17'); 
INSERT INTO table1 VALUES (4, 'abcd', 1, '2010-08-08 17:23:22'); 
INSERT INTO table1 VALUES (5, 'efg1', 5, '2010-07-10 21:36:55'); 
INSERT INTO table1 VALUES (6, 'c123', 5, '2010-07-10 20:44:36'); 
INSERT INTO table1 VALUES (7, 'bbey', 12, '2010-08-09 09:01:26'); 

Résultat:

+------+------+---------------------+ 
| data | type | date    | 
+------+------+---------------------+ 
| abcd | 1 | 2010-08-08 17:23:22 | 
| some | 2 | 2010-08-07 18:07:32 | 
| efg1 | 5 | 2010-07-10 21:36:55 | 
| data | 9 | 2010-08-06 02:52:17 | 
| bbey | 12 | 2010-08-09 09:01:26 | 
+------+------+---------------------+ 
5 rows in set (0.00 sec) 

Il a également semble que vous pouvez éviter les sous-requêtes tout à fait, en utilisant une solution telle que la suivante:

SELECT  t1.`data`, t1.`type`, t1.`date` 
FROM  `table1` t1 
LEFT JOIN `table1` t2 ON (t1.`date` < t2.`date` AND t1.`type` = t2.`type`) 
WHERE  t2.`date` IS NULL 
GROUP BY t1.`type` 
ORDER BY t1.`type`, t1.`date`; 

En général, cette échelles encore mieux que la solution avec la table dérivée, mais si la performance est primordiale, vous pouvez mesurer les deux solutions. L'article que @Naktibalda fourni fournit également quelques autres solutions que vous pouvez vouloir tester.