-
Есть таблицы
`auto` - столбцы: `id`, `number` (автомобили)
`client` - столбцы: `id`, `name`
И связывающая их таблица заказов:
`order` - столбцы `id`, `auto_id`, `client_id`, `create_time`
Для одного и того же автомобиля может быть сколько угодно заказов как от одного так и от нескольких клиентов.
Нужно получить список автомобилей и присоединить Имя последнего заказчика.
Пока у меня несколько вариантов, которые меня не устраивают:
1. Добавить в таблицу `auto` поле, где кешировать `client`.`id` последнего клиента. - не удобно поддерживать данное поле.
2. Добавить в простой запрос из таблицы `auto` вложенный запрос - может быть очень медленно.
А как сделать присоединением JOIN я пока не могу представить.
Ваши предложения?
БД: MySQL
-
Если правильно понял, то примерно так (выборка полей от фонаря, поставь сам нужные) - выбираться должны авто имеющие заказы и последний клиент сделавший заказ на авто
select a.number,c.name,o.id
from auto a
inner join orders o
--(не нравится мне название order)
ON o.auto_id=a.id
inner join client c on c.id=o.client.id
where o.create_time=(select MAX(o1.create_time) from orders o1 where o1.auto_id=a.id)
PS: Запрос не проверял, написал навскидку.
-
> select MAX(o1.create_time) from orders o1 where o1.auto_id=a.
> id
Логически верно, а с точки зрения производительности?
MySQL будет этот запрос выполнять для каждой строки?
-
> Дмитрий С © (20.01.10 08:53) [2]
Сорри, по производительности не скажу. Не знаю MYSQL
Но при наличии индексов мне кажется тормозить не должно. План запроса покажет узкие места. Если запрос сильно тормозит, попробую подумать еще...
-
select a.number,c.name,o.id
,MAX(o.create_time)
from auto a
inner join orders o ON o.auto_id=a.id
inner join client c on c.id=o.client.id
group by a.number,c.name,o.id
-
> [2] Дмитрий С © (20.01.10 08:53)
> а с точки зрения производительности?
А каковы объемы БД? А какие индексы есть? А попробовать наконец?
-
> turbouser © (20.01.10 09:10) [4]
Попробовал - выдает не то, что нужно (даже количество записей другое)
Можно прокомментировать?
-
> Sergey13 © (20.01.10 09:42) [5]
>
> А каковы объемы БД? А какие индексы есть? А попробовать
> наконец?
База проектируется пока, данных в ней почти нет пока.
Индексы будут добавлены под запросы.
-
> [7] Дмитрий С © (20.01.10 09:46)
Ну а предполагаемый объем БД? А объем выборки?
Что это - такси?
-
> Sergey13 © (20.01.10 09:50) [8]
Программа для автосервиса.
Около 2000 заказов в год.
Клиентов в два раза меньше, автомобилей столько же.
Запрос нужен для получения списка автомобилей (с фильтром), где указывается имя последнего клиента, что сдавал его в ремонт. Желательно по нему тоже фильтр сделать.
-
Запрос будет выполняться каждый раз, как будет редактироваться фильтр. Т.е. пользователь нажимает клавишу в поле фильтра - запрос выполнился - клиент увидел результат. Поэтому хочется, чтобы запрос выполнялся моментально.
В запросе будет добавлено LIMIT 100
-
>Дмитрий С © (20.01.10 08:53) [2]
>Логически верно, а с точки зрения производительности?
логически неверно, т.к. надо выбирать максимальный ORDERS.ID (если автоинкрементное) соответствующий максимальному времени
всё остальное - частные решения, существующие при ряде допущений
выполняться будет быстро при наличии соответствующих индексов
-
> [9] Дмитрий С © (20.01.10 10:04)
> Около 2000 заказов в год.
> Клиентов в два раза меньше, автомобилей столько же.
Детские объемы. Не парься. В крайнем случае индекс по o1.create_time+o1.auto_id должен здорово помочь.
Какой то странный у тебя автосервис. Для колхоза что ли? Много людей сдают много машин в разных сочетаниях. Странно как то.
Я бы поставил во главу угла документ на проведение ремонта, по которому происходит оплата работы клиентом. Для обычного сервиса справочники авто и клиентов в принципе не обязательны (хоть и не помешают разумеется). ИМХО.
-
turbouser © (20.01.10 09:10) [4]
нужно не время последнего заказа по каждому клиенту и автомобилю, а клиента, последним заказывавшего)
-
>Sergey13 © (20.01.10 10:29) [12]
>В крайнем случае индекс по o1.create_time+o1.auto_id должен здорово помочь.
т.е. два индекса: один - на orders.auto_id, другой - на orders.id
-
> Sergey13 © (20.01.10 10:29) [12]
Я вот тоже думаю, убрать справочник клиентов. Добавить Имя к заказу и все. В случае чего можно будет сделать группировку по Имени.
-
>Дмитрий С © (20.01.10 11:01) [15]
если нет разницы между Васисуалием Правдорубом пятнадцати лет от роду и однофамильцем Васисуалием восьмидесяти пяти лет, то и в справочнике нет необходимости, но тогда не ясно, зачем вообще надо показывать последнего клиента - ведь кто он конкретно неизвестно
-
к Кщд (20.01.10 11:50) [16]
денормализацию проводят для эффективности получения данных, но отнюдь не из-за лени, т.к. чревато
-
> [14] Кщд (20.01.10 10:33)
Для конкретно этой выборки (из [1]) был бы полезен один составной индекс по auto_id+create_time. Теоретически подзапрос не должен вообще лезьть в таблицу - все данные есть в этом индексе. ИМХО.
-
> Дмитрий С (20.01.2010 08:16:00) [0]
Что такое Имя последнего заказчика, для меня это когда уже больше заказчиков не будет, квалификацие распугал.