Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / GROUP BY, DISTINCT и ORDER BY (оптимизация) / 11 сообщений из 11, страница 1 из 1
10.06.2018, 11:01
    #39659201
General4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
GROUP BY, DISTINCT и ORDER BY (оптимизация)
Добрый день, уважаемые эксперты.

Версия сервера MySQL: 5.7.21
Таблица:
idсделанопереданообъект101400200400311400421400511500601500
Легенда:
сделано: 0 - в процессе, 1 - сделано, 2 - отменено
передано: 0 - не передано, 1 - передано (упрощено до 0,1, а так здесь стоят даты)

Запрос:
Код: sql
1.
2.
3.
4.
SELECT id, сделано, передано, объект, COUNT(объект) FROM 
  (SELECT DISTINCT id, сделано, передано, объект FROM заявки
    ORDER BY сделано, передано) т
  GROUP BY т.объект ORDER BY объект DESC



Результат:
idсделанопереданообъектзаданий60150022004004
В приоритете, чтобы GROUP BY отбирал результат по "передано"=0, а потому уже по "сделано"=0. Данный запрос работает корректно и со своей задачей справляется.

Вопрос: Можно ли оптимизировать данный запрос, чтобы время выполнения было ещё меньше, например использовать min и JOIN, и исключить DISTINCT и ORDER BY?
Если, да, то можно ли скелет запроса, остальное я додумаю сам.
Спасибо.
...
Рейтинг: 0 / 0
10.06.2018, 11:37
    #39659206
982183
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
GROUP BY, DISTINCT и ORDER BY (оптимизация)
Код: sql
1.
SELECT DISTINCT id, сделано, передано, объект FROM заявки ORDER BY сделано, передано



А в чем смысл подзапроса?
id и так уникальный.
А сортировка бессмысленна.
...
Рейтинг: 0 / 0
10.06.2018, 11:41
    #39659208
982183
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
GROUP BY, DISTINCT и ORDER BY (оптимизация)
Код: sql
1.
2.
SELECT id, сделано, передано, объект, COUNT(объект) FROM заявки
 GROUP BY объект ORDER BY объект DESC


Результат должен быть тем же.

только непонятно почему у тебя это работает без агрегирующих функций.
...
Рейтинг: 0 / 0
10.06.2018, 11:49
    #39659213
982183
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
GROUP BY, DISTINCT и ORDER BY (оптимизация)
General4В приоритете, чтобы GROUP BY отбирал результат по "передано"=0, а потому уже по "сделано"=0.
Я правильно понимаю:
Над вывести записи ID с минимальным "сделано", если "сделано несколько", то выбрать с минимальным "передано"
в разрезе "объект"
...
Рейтинг: 0 / 0
10.06.2018, 12:43
    #39659228
General4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
GROUP BY, DISTINCT и ORDER BY (оптимизация)
Нет, не с минимальным id. В поставленной задаче id не имеет значение. Здесь главное Объект. Это сводная таблица
Если даже попадутся два одинаковых результата - выбрать нужно любой. Так как в программе номер Объекта играет первостепенную роль.
Код: sql
1.
2.
SELECT id, сделано, передано, объект, COUNT(объект) FROM заявки
 GROUP BY объект ORDER BY объект DESC


Нет результат будет другой, проверено.
Смысл подзапроса это формирование временной таблицы, её сортировка в начале по Сделано, потом по Передано, потом GROUP BY берёт первую строку из временной таблицы.
Сделано и Передано играют роль раскраски строки в StringGrid. Поэтому и есть приоритет. Вначале передано=0 - цвет оранжевый, а потом уже сделано=1 - зелёный или 2 - серый (отменено).
Запрос проверен и работает в программе. Вопрос в оптимизации. Нужна ли оптимизация здесь или этот запрос по скорости имеет окончательный вариант.
...
Рейтинг: 0 / 0
10.06.2018, 13:03
    #39659233
General4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
GROUP BY, DISTINCT и ORDER BY (оптимизация)
982183Я правильно понимаю:
Над вывести записи ID с минимальным "сделано", если "сделано несколько", то выбрать с минимальным "передано"
в разрезе "объект"
Чуть-чуть наоборот :) Надо сформировать группу объектов, где каждому объекту выбрать минимальную "передано" - первую попавшуюся, а после минимально "сделанную" - первую попавшуюся.
И получается, что строка в StringGrid разукрасится оранжевым, если хотя бы одна запись заявок для объекта будет не передана. Без DISTINCT это не работает, GROUP BY берёт первую попавшуюся из временной таблицы.
Вопрос тогда поставлю по другому: Как заставить GROUP BY взять именно ту запись, учитывая приоритет поставленной задачи. :)
...
Рейтинг: 0 / 0
10.06.2018, 17:25
    #39659303
General4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
GROUP BY, DISTINCT и ORDER BY (оптимизация)
Решение!
Натолкнул на мысль участник: 982183
Отвечаю сам же :)

Исходный неоптимизированный запрос:
Код: sql
1.
2.
3.
4.
SELECT id, сделано, передано, объект, COUNT(объект) FROM 
  (SELECT DISTINCT id, сделано, передано, объект FROM заявки
    ORDER BY сделано, передано) т
  GROUP BY т.объект ORDER BY объект DESC


Время выполнения запроса: 634,02 мкс

Оптимизированное решение:
Код: sql
1.
SELECT id, объект, COUNT(объект), min(сделано), min(передано) FROM заявки GROUP BY объект ORDER BY объект DESC


Время выполнения запроса: 379,45 мкс

Примечание: Созданные поля min(сделано), min(передано) являются для StringGrid определяющими в раскраске строк.

Вопрос закрыт.
...
Рейтинг: 0 / 0
11.06.2018, 04:25
    #39659366
982183
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
GROUP BY, DISTINCT и ORDER BY (оптимизация)
В этом случае ты можешь получить id, не соответствующие min(сделано) и min(передано)
...
Рейтинг: 0 / 0
11.06.2018, 05:27
    #39659371
General4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
GROUP BY, DISTINCT и ORDER BY (оптимизация)
982183В этом случае ты можешь получить id, не соответствующие min(сделано) и min(передано)
Хорошо, ещё упрощаю :) Чтобы уже точно никто не подумал более, что мне важен id :)
Код: sql
1.
SELECT объект, COUNT(объект), min(сделано), min(передано) FROM заявки GROUP BY объект ORDER BY объект DESC



P.S.: Таблица сводная. Потом по номеру объекта вычисляются все заявки и выводятся во второй StringGrid, вот там id важен. :)
...
Рейтинг: 0 / 0
11.06.2018, 05:44
    #39659372
982183
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
GROUP BY, DISTINCT и ORDER BY (оптимизация)
Так это совершенно другая задача.
"вывести минимальные (сделано) и (передано) в разрезе объектов"
Или на
"Вывести минимальную дату(передано) по объектам "в процессе"
...
Рейтинг: 0 / 0
11.06.2018, 06:06
    #39659376
General4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
GROUP BY, DISTINCT и ORDER BY (оптимизация)
982183, Да я уже понял, перечитав себя. В следующий раз сформулирую вопрос более конкретно. Как говорится, исправлюсь :)

И чтобы ответ был более полный.
Запрос:
Код: sql
1.
SELECT объект, COUNT(объект) AS заданий, min(сделано) AS сделано, min(передано) AS передано, max(контроль) AS контроль FROM заявки GROUP BY объект ORDER BY объект DESC



Обращение из Delphi:
Код: pascal
1.
2.
3.
4.
if FieldByName('контроль').AsDateTime <> 0 then Cells[5,i] := FieldByName('контроль').AsString;
Cells[6,i] := FieldByName('заданий').AsString;
Cells[8,i] := FieldByName('сделано').AsString;
if FieldByName('передано').AsDateTime = 0 then Cells[9,i] := '1';


P.S.: поле "контроль" - тип DATETIME. Из всех записей по конкретному объекту ищется максимальная дата по полю "контроль".
idсделанопереданообъектконтрольпримечание101400NULL2004001899-12-30 00:00:003114002017-01-29 10:32:254214002018-06-11 11:00:00эта строка будет в поле "контроль"
Для Delphi, что 1899-12-30 00:00:00, что NULL это = 0.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / GROUP BY, DISTINCT и ORDER BY (оптимизация) / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]