Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Помогите составить запрос / 25 сообщений из 26, страница 1 из 2
06.03.2018, 11:53
    #39611093
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
Упрощу структуру, чтобы не путаться в специфике базы:
Есть таблица master m и detail d.
Нужно вывести запрос строк из master + значение, говорящее о том, что для master СУЩЕСТВУЮТ значения в detail-таблице, и при этом дата окончания ни в одном из них непустая.
Сейчас запрос выглядит следующим образом:
авторSELECT m.*, (IF ((d_ex.id IS NOT NULL) AND (d_nul.id IS NULL), 'Y', 'N')) AS all_finished // lдетайлы существуют и нет незавершенных
FROM master m
LEFT JOIN detail d_ex ON d_ex.master_id = m.id // существование детайлов
LEFT JOIN detail d_nul ON (d_nul.master_id = m.id) AND ((d_nul.finish_time = '1899-12-30') OR (d_nul.finish_time IS NULL)) // присутствие незавершенных среди существующих

Однако выполняется он очень долго - 14 секунд.
Как только закомментируешь хотя бы один из этих джойнов, скорость возрастает до 2 секунд.
Но как тогда вместить все в один джойн, если это противоположные требования? В первом надо определить существование, а во втором - несуществование.
...
Рейтинг: 0 / 0
06.03.2018, 11:58
    #39611098
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
Упрощу структуру, чтобы не путаться в специфике базы:
Есть таблица master m и detail d.
Нужно вывести запрос строк из master + значение, говорящее о том, что для master СУЩЕСТВУЮТ значения в detail-таблице, и при этом дата окончания ни в одном из них непустая.
Сейчас запрос выглядит следующим образом:

Код: sql
1.
2.
3.
4.
SELECT m.*, (IF ((d_ex.id IS NOT NULL) AND (d_nul.id IS NULL), 'Y', 'N')) AS all_finished // lдетайлы существуют и нет незавершенных
FROM master m
LEFT JOIN detail d_ex ON d_ex.master_id = m.id // существование детайлов
LEFT JOIN detail d_nul ON (d_nul.master_id = m.id) AND ((d_nul.finish_time = '1899-12-30') OR (d_nul.finish_time IS NULL)) // присутствие незавершенных среди существующих



Однако выполняется он очень долго - 14 секунд.
Как только закомментируешь хотя бы один из этих джойнов, скорость возрастает до 2 секунд.
Но как тогда вместить все в один джойн, если это противоположные требования? В первом надо определить существование, а во втором - несуществование.
...
Рейтинг: 0 / 0
06.03.2018, 12:08
    #39611106
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
svnvladЕсть таблица master m и detail d.
Нужно вывести запрос строк из master + значение, говорящее о том, что для master СУЩЕСТВУЮТ значения в detail-таблице, и при этом дата окончания ни в одном из них непустая.

Код: sql
1.
2.
3.
4.
5.
SELECT m.*
     , MAX(d.master_id) IS NULL DetailsNotExist
     , MAX(d.finish_time) > '1899-12-30' NullsNotExist
FROM master m
LEFT JOIN detail d ON d.master_id = m.id
...
Рейтинг: 0 / 0
06.03.2018, 12:09
    #39611110
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
Одно плохо - значения-признаки будут дублироваться в каждой записи... некошерно... почему не получить их вторым запросом?
...
Рейтинг: 0 / 0
06.03.2018, 12:11
    #39611112
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
А, да... GROUP BY m.id либо просто DISTINCT добавь. А то для тех записей, для которых есть соответствия более одного, вылезут дубли.
...
Рейтинг: 0 / 0
06.03.2018, 12:16
    #39611117
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
AkinaА, да... GROUP BY m.id либо просто DISTINCT добавь. А то для тех записей, для которых есть соответствия более одного, вылезут дубли.
Да, там есть, я просто забыл здесь написать.
...
Рейтинг: 0 / 0
06.03.2018, 14:41
    #39611237
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
AkinaОдно плохо - значения-признаки будут дублироваться в каждой записи... некошерно... почему не получить их вторым запросом?
Это сообщение не понял.
...
Рейтинг: 0 / 0
06.03.2018, 14:54
    #39611247
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
AkinasvnvladЕсть таблица master m и detail d.
Нужно вывести запрос строк из master + значение, говорящее о том, что для master СУЩЕСТВУЮТ значения в detail-таблице, и при этом дата окончания ни в одном из них непустая.

Код: sql
1.
2.
3.
4.
5.
SELECT m.*
     , MAX(d.master_id) IS NULL DetailsNotExist
     , MAX(d.finish_time) > '1899-12-30' NullsNotExist
FROM master m
LEFT JOIN detail d ON d.master_id = m.id


Если первое верно MAX(d.master_id) IS NULL DetailsNotExist,
то второе MAX(d.finish_time) > '1899-12-30' NullsNotExist не дает правильного результата.
...
Рейтинг: 0 / 0
06.03.2018, 15:09
    #39611265
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
svnvladMAX(d.finish_time) > '1899-12-30' NullsNotExist не дает правильного результата.
Да, точно. Замени на
Код: sql
1.
MIN(COALESCE(d.finish_time, '1899-12-30')) > '1899-12-30' NullsNotExist
...
Рейтинг: 0 / 0
06.03.2018, 15:10
    #39611266
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
EMS MySQL Manager странно работает. Вношу с его помощью в дату значение '1899-30-12 00:00:00', он превращает его в 0000-00-00 00:00:00', соответственно, запрос его не находит как WHERE finish_time = '1899-12-30', однако, находит как WHERE finish_time = 0.
С другой стороны, в базе реально есть значения "1899-12-30 00:00:00", и их он находит как WHERE finish_time = '1899-12-30'.
Получается на нулевое значение даты надо проверять по 3-м признакам?
1. NULL
2. 1899-12-30
3. 0
...
Рейтинг: 0 / 0
06.03.2018, 15:16
    #39611271
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
Akina,
а вот так тоже нормально?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT m.*,
       MAX(d.master_id) IS NULL DetailsNotExist,

       EXISTS(SELECT d.id FROM detail d 
              WHERE d.master_id = m.id
              AND ((d.finish_time IS NULL) OR (d.finish_time = 0) OR (d.finish_time = '1899-12-30'))) NullsExist

FROM master m
LEFT JOIN detail d ON d.master_id = m.id
GROUP BY m.id
...
Рейтинг: 0 / 0
06.03.2018, 15:40
    #39611290
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
svnvladа вот так тоже нормально?Нет. Коррелированный подзапрос скорее всего снизит скорость выполнения. SUM(условие1 OR условие2 OR ...) скорее всего будет быстрее.

svnvladEMS MySQL Manager странно работает. Вношу с его помощью в дату значение '1899-30-12 00:00:00', он превращает его в 0000-00-00 00:00:00'
https://dev.mysql.com/doc/refman/5.7/en/datetime.html Invalid DATE, DATETIME, or TIMESTAMP values are converted to the “zero” value of the appropriate type ('0000-00-00' or '0000-00-00 00:00:00').
Опять же смотрим SQL Modes.
И эта... какой точно тип данных у поля?
...
Рейтинг: 0 / 0
06.03.2018, 16:29
    #39611323
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
Akina,

тип DATETIME.
...
Рейтинг: 0 / 0
06.03.2018, 16:31
    #39611326
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
Немного усложним задачу. На самом деле в таблице detail не одна ссылка master_id, а две.
from_master_id и to_master_id. Заполняется только одна из них, либо from_master_id, либо to_master_id.
Соответственно, другая будет Null.
И тут у меня возникают трудности, как данный запрос адаптировать к этой системе.
...
Рейтинг: 0 / 0
06.03.2018, 16:54
    #39611346
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
Вроде бы решил
Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT m.*,
MAX(COALESCE(d.from_master_id, d.to_master_id)) IS NOT NULL DetailsExist,
MIN(COALESCE(d.finish_time, '1899-12-30')) > '1899-12-30' NullsNotExist

FROM master m
LEFT JOIN detail d ON m.id IN (d.from_master_id, d.to_master_id)
GROUP BY m.id
...
Рейтинг: 0 / 0
06.03.2018, 16:54
    #39611347
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
svnvladтип DATETIME.
https://dev.mysql.com/doc/refman/5.7/en/datetime.html The DATETIME type is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'.
Так что '1899-30-12 00:00:00' - вполне себе легитимное значение для этого типа поля. А наблюдаемая проблема - хороший повод деинсталлировать глючный софт и перейти на нечто более вменяемое.

svnvladНа самом деле в таблице detail не одна ссылка master_id, а две.
from_master_id и to_master_id. Заполняется только одна из них, либо from_master_id, либо to_master_id.
Соответственно, другая будет Null.Ну привязывай две копии и используй COALESCE для выбора Not-NULL значения из двух. Делов-то... впрочем, что бы с учётом этого бреда не подумать об изменении структурки?
...
Рейтинг: 0 / 0
06.03.2018, 17:01
    #39611354
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
Akinasvnvladтип DATETIME.
https://dev.mysql.com/doc/refman/5.7/en/datetime.html The DATETIME type is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'.
Так что '1899-30-12 00:00:00' - вполне себе легитимное значение для этого типа поля. А наблюдаемая проблема - хороший повод деинсталлировать глючный софт и перейти на нечто более вменяемое.

Да он еще при добавлении или изменении записей в таблицы, даже если фиксируешь транзакцию, в упор не видит изменений, пока не отсоединишься от базы и не присоединишься вновь. А какой софт не глючный, конкурентоспособный по сравнению с EMS?

svnvladНа самом деле в таблице detail не одна ссылка master_id, а две.
from_master_id и to_master_id. Заполняется только одна из них, либо from_master_id, либо to_master_id.
Соответственно, другая будет Null.Ну привязывай две копии и используй COALESCE для выбора Not-NULL значения из двух. Делов-то... впрочем, что бы с учётом этого бреда не подумать об изменении структурки?
Там выше, уже решил.
По поводу структуры, тут master - это карточка груза (включает местоположение), а detail - это операции перегрузки, в ней отражается с какой карточки в какую груз был перегружен. Поэтому, собственно, сама карточка остается master-ом, а в detaile две ссылки - на карточку "откуда", и на карточку "куда".
...
Рейтинг: 0 / 0
06.03.2018, 19:28
    #39611455
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
svnvladкакой софт не глючный, конкурентоспособный по сравнению с EMS?А это от необходимого функционала зависит. Но со штатными консолью и воркбенчем такой хни, как ты рассказываешь, точно не бывает...
...
Рейтинг: 0 / 0
06.03.2018, 19:29
    #39611456
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
svnvladdetail - это операции перегрузки, в ней отражается с какой карточки в какую груз был перегружен.Избыточно и потенциально противоречиво. Достаточно информации, куда. А откуда - определяется уже имеющимися данными.
...
Рейтинг: 0 / 0
06.03.2018, 20:06
    #39611469
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
AkinaТак что '1899-30-12 00:00:00' - вполне себе легитимное значение для этого типа поля.Не понял, почему? 30 месяц не бывает же?
...
Рейтинг: 0 / 0
06.03.2018, 20:17
    #39611475
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
miksoftпочему? 30 месяц не бывает же?Блин, даже не посмотрел... вначале ж везде '1899-12-30' было... раз проверил и забыл.
...
Рейтинг: 0 / 0
07.03.2018, 13:59
    #39611827
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
Akinasvnvladdetail - это операции перегрузки, в ней отражается с какой карточки в какую груз был перегружен.Избыточно и потенциально противоречиво. Достаточно информации, куда. А откуда - определяется уже имеющимися данными.
А как отобразить такой процесс?
Приехало 10 автомобилей с грузом. Каждая партия этого груза - это отдельная карточка. В данном случае на одном автомобиле одна карточка груза. Включает в себя номер договора, вес, условия перевозки, ссылка на автомобиль.
Эти 10 авто разгружают на склад №1 в одну кучу, формируя таким образом новую карточку - карточку груза склада. Она включает номер договора, вес (в ней уже суммированные веса всех 10 партий), № склада.
В существующей схеме в таблице transshipment имеется ссылка from_cargo_card_id и to_cargo_card_id. Соответственно в ней сформируется 10 строк, отражающих историю всех перегрузок, их продолжительность, ответственного и т.д.
...
Рейтинг: 0 / 0
07.03.2018, 14:03
    #39611833
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
А еще один автомобиль могут разгружать не единоразово, а в 2 смены. В transshipment сформируется тогда 2 записи, отражающие историю всей перегрузки. А если просто в карточке делать ссылку "куда", то 2 операции не отобразить.
...
Рейтинг: 0 / 0
07.03.2018, 14:07
    #39611835
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
И еще теоретически могут карточку одного автомобиля разгрузить частично на один склад, частично на другой, т.е. в 2 разных карточки.
...
Рейтинг: 0 / 0
07.03.2018, 15:04
    #39611893
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите составить запрос
Тебе надо почитать про складской учёт. Причём почитать серьёзно. А хранить или возить - совершенно неважно.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Помогите составить запрос / 25 сообщений из 26, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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