Requête MySQL: LIMITER une JOIN
-
03-07-2019 - |
Question
Disons que je souhaite rejoindre deux tables. Catégories:
id name
----------
1 Cars
2 Games
3 Pencils
Et les articles:
id categoryid itemname
---------------------------
1 1 Ford
2 1 BMW
3 1 VW
4 2 Tetris
5 2 Pong
6 3 Foobar Pencil Factory
Je veux une requête qui retourne la catégorie et le premier (et seulement le premier) itemname:
category.id category.name item.id item.itemname
-------------------------------------------------
1 Cars 1 Ford
2 Games 4 Tetris
3 Pencils 6 Foobar Pencil Factory
Et y a-t-il un moyen d'obtenir des résultats aléatoires tels que:
category.id category.name item.id item.itemname
-------------------------------------------------
1 Cars 3 VW
2 Games 5 Pong
3 Pencils 6 Foobar Pencil Factory
Merci!
La solution
Je viens de faire un test rapide. Cela semble fonctionner:
mysql> select * from categories c, items i
-> where i.categoryid = c.id
-> group by c.id;
+------+---------+------+------------+----------------+
| id | name | id | categoryid | name |
+------+---------+------+------------+----------------+
| 1 | Cars | 1 | 1 | Ford |
| 2 | Games | 4 | 2 | Tetris |
| 3 | Pencils | 6 | 3 | Pencil Factory |
+------+---------+------+------------+----------------+
3 rows in set (0.00 sec)
Je pense que cela répondrait à votre première question. Pas sûr de la seconde - je pense qu'il faut une requête interne avec order by random () ou quelque chose comme ça!
Autres conseils
Mysql vous permet d’avoir des colonnes non incluses dans le groupe ou l’agrégat, auquel cas elles ont des valeurs aléatoires:
select category.id, category.name, itemid, itemname
inner join
(select item.categoryid, item.id as itemid, item.name as itemname
from item group by categoryid)
on category.id = categoryid
Ou, pour les minimums,
select category.id, category.name, itemid, itemname
inner join
(select item.categoryid, min(item.id) as itemid, item.name as itemname
from items
group by item.categoryid)
on category.id = categoryid
Mysql laisse inclure des colonnes non agrégées et il n’ya aucune garantie de déterminisme, mais selon mon expérience, j’obtiens presque toujours les premières valeurs.
Donc généralement (mais pas garanti) cela vous donnera le premier
select *
from categories c, items i
where i.categoryid = c.id
group by c.id;
Si vous voulez avoir la garantie de faire quelque chose comme
select categories.id, categories.name, items.id, items.name
from categories inner join
items on items.categoryid = categories.id and
items.id = (select min(items2.id) from items as items2 where items2.categoryid = category.id)
Si vous voulez des réponses aléatoires, vous devrez changer un peu la sous-requête
select categories.id, categories.name, items.id, items.name
from categories inner join
items on items.categoryid = categories.id and
items.id = (select items2.id from items as items2 where items2.categoryid = category.id order by rand() limit 1)