Запрос MySQL: ОГРАНИЧЕНИЕ СОЕДИНЕНИЯ

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

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

Спасибо!

Как вы определяете «первый»? Похоже, наименьшее значение ID в элементе?

Matt Rogish 02.10.2008 19:36

Ага, моя плохая. Под первым я подразумеваю самый низкий идентификатор.

ehm 02.10.2008 20:07
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
5
2
1 731
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

При использовании этого метода у меня возникла ошибка: «Каждая производная таблица должна иметь собственный псевдоним». Думаю, я где-то сделал что-то не так.

ehm 02.10.2008 20:22
Ответ принят как подходящий

Только что сделал быстрый тест. Кажется, это работает:

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 () или что-то в этом роде!

Для меня не так важно, чтобы результаты были случайными, так что это было действительно то, что я искал! Спасибо

ehm 02.10.2008 20:06

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)

Другие вопросы по теме