Скажем, у меня есть два стола, к которым я хочу присоединиться. Категории:
id name
----------
1 Cars
2 Games
3 Pencils
И предметы:
id categoryid itemname
---------------------------
1 1 Ford
2 1 BMW
3 1 VW
4 2 Tetris
5 2 Pong
6 3 Foobar Pencil Factory
Мне нужен запрос, который возвращает категорию и первое (и только первое) имя элемента:
category.id category.name item.id item.itemname
-------------------------------------------------
1 Cars 1 Ford
2 Games 4 Tetris
3 Pencils 6 Foobar Pencil Factory
И есть ли способ получить случайные результаты, например:
category.id category.name item.id item.itemname
-------------------------------------------------
1 Cars 3 VW
2 Games 5 Pong
3 Pencils 6 Foobar Pencil Factory
Спасибо!
Ага, моя плохая. Под первым я подразумеваю самый низкий идентификатор.






Mysql позволяет вам иметь столбцы, не включенные в группировку или агрегирование, и в этом случае они имеют случайные значения:
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
Или, для минимума,
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> 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)
Думаю, это отвечало бы на ваш первый вопрос. Не уверен насчет второго - я думаю, что для этого нужен внутренний запрос с order by random () или что-то в этом роде!
Для меня не так важно, чтобы результаты были случайными, так что это было действительно то, что я искал! Спасибо
Mysql позволяет включать неагрегированные столбцы, и нет никакой гарантии детерминизма, но по моему опыту я почти всегда получаю первые значения.
Обычно (но не гарантируется) это даст вам первый
select *
from categories c, items i
where i.categoryid = c.id
group by c.id;
Если вы хотите гарантированно, вам нужно будет сделать что-то вроде
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)
Если вам нужны случайные ответы, вам придется немного изменить подзапрос
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)
Как вы определяете «первый»? Похоже, наименьшее значение ID в элементе?