2008-10-02 2 views
5

Скажем, у меня есть две таблицы, в которые я хочу присоединиться. Категории:MySQL Query: LIMITing JOIN

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 

Я хочу, чтобы запрос, который возвращает категорию и первый (и только первым) ItemName:

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 

Спасибо!

+0

Как вы определяете "First"? Он выглядит как минимальное значение ID в элементе? – 2008-10-02 15:36:45

+0

Да, мое плохое. Сначала я имею в виду самый низкий идентификатор. – Eikern 2008-10-02 16:07:52

ответ

6

Просто сделать быстрое контрольная работа. Это, как представляется, работает:

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) 

Я думаю, что это выполнит ваш первый вопрос. Не уверен, что второй - я думаю, что для запроса внутреннего запроса нужен случайный() или что-то в этом роде!

0

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 
+0

У меня возникла ошибка, когда я попробовал этот метод: «Каждая производная таблица должна иметь свой собственный псевдоним». Наверное, я что-то сделал не так. – Eikern 2008-10-02 16:22:17

0

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)