|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Есть таблица идентификаторов товаров: Код: sql 1. 2.
Содержание: Код: plaintext
Есть три таблицы, где есть расход по этим товарам: Код: sql 1. 2. 3.
Содержание: Код: plaintext
[USAGE2] Код: sql 1. 2.
Содержание: Код: plaintext 1.
[USAGE3] Код: sql 1. 2.
Содержание: Код: plaintext 1. 2.
Нужно одним запросом посчитать суммы по всем трем таблицам: Код: sql 1. 2. 3. 4. 5. 6.
Получаю это: Код: plaintext 1.
Ну и без группировки это выглядит так: Код: plaintext 1. 2. 3. 4. 5. 6.
Какой JOIN мне нужно использовать чтобы данные не дублировались? Сейчас делаю три отдельных запроса, но это очень некрасиво. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 08:25 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1, тебе нужен не JOIN, а UNION из SELECT'ов сумм, если хочешь суммы построчно. Если хочешь суммы по столбцам, то нужен один SELECT, у которого значение каждого поля суммы представлено результатом суммирующего SELECT'а. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 09:06 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1 Код: plaintext 1. 2.
rdb_dev тебе нужен не JOIN, а UNION из SELECT'ов сумм Надеюсь, понимаешь разницу между UNION и UNION ALL? ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 11:06 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
wadman, ALL, это опция UNION. Возьмёт Reference Manual и разберётся. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 12:56 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
не разберётся. это тестовая задача. дорога' ложка к обеду. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 12:59 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Мимопроходящий, значит в этот раз повезёт тестирующему, а не тестируемому. Знавал я одного ребятёнка, который после ВУЗа с дипломом программиста пытался устроиться в Корус вообще без знаний, что такое СУБД и чем её едят. Корусу повезло, ребятёнку нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 13:07 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
rdb_dev Rom1, тебе нужен не JOIN, а UNION. Но ведь UNION создаёт новую временную таблицу (в MySQL, в Firebrd не знаю), это же даст отрицательный результат производительности? ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 16:26 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Мимопроходящий не разберётся. это тестовая задача. дорога' ложка к обеду. Молодой человек, с чего вы взяли что я студент? ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 16:27 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1, не создаёт он никаких временных таблиц, уж в ФБ точно. UNION в отличие от UNION ALL требует сортировку для удаления дубликатов и вот тут есть потеря производительности. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 16:34 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Симонов Денис UNION в отличие от UNION ALL требует сортировку для удаления дубликатов и вот тут есть потеря производительности. Еще хуже, когда плюс потеря данных в некоторых случаях, как выше. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 16:35 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Хорошо, если я вынесу (вынес) все эти "три" запроса в процедуру (ранее выполнял их на клиенте), а процедура выдаёт агрегированный результат, насколько это может отличаться по производительности по сравнению с UNION? ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 16:38 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1, а чем вот такой вариант не подходит? Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 16:53 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
KreatorXXI Rom1, а чем вот такой вариант не подходит? Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
Да, сам уже дошел до такого: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
Результат: Код: plaintext 1. 2. 3. 4. 5. 6.
Честно говоря, если встречу такой запрос в коде, решу что его писал наркоман. "from GOODS" у меня не просто таблица, а ресурсоёмкий запрос по выборке товаров, по которым надо сделать такую агрегацию, поэтому сделать его хочу один раз за запрос. А вот трижды делать его - полный провал. Как и в вашем примере, если гудсов тысяча, то запросов будет три тысячи, если я правильно понимаю, а это тоже фейл. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 17:03 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1с чего вы взяли что я студент? Слишком кривая схема данных, слишком странное требование "одним запросом". Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 17:10 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1, причём тут GOODS1, если в запросе KreatorXXI он вычитывается ровно один раз. Это к его результатам добавляются результаты 3-х подзапросов ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 17:11 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1, можно и таким образом сделать: Код: sql 1. 2.
... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 17:14 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov Слишком кривая схема данных, слишком странное требование "одним запросом". Ничего кривого не вижу. Требование простое "отдать всю работу с клиента на сервер", в идеале одним запросом. Симонов Денис Rom1, причём тут GOODS1, если в запросе KreatorXXI он вычитывается ровно один раз. Это к его результатам добавляются результаты 3-х подзапросов Я не знаю как СУБД устроена внутри, возможно будет основной запрос товаров, после идентификаторы сериализуются и передаются в те три запроса, в результате имеем четыре запроса. Может быть и так, я не знаю, пусть эксперты подтвердят. Лично я смотрю "в лоб" и вижу в этом примере, что на каждый товар по три запроса, 1000 товаром, 3000 запросов. Но может это и не так, я же написал - "насколько понимаю". wadman Rom1, можно и таким образом сделать: [/src] KreatorXXI уже привел подобный пример ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 17:25 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1Ничего кривого не вижу. Три разные таблицы с общим назначением "расход" и совершенно одинаковой структурой. Так БД обычно не делают. Rom1Требование простое "отдать всю работу с клиента на сервер", в идеале одним запросом. Вот этот "идеал" - как раз студенческий уровень. Три простых отдельных запроса часто быстрее одного хитроподвыподвертнутого. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 17:47 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
У дубликатов значений полей в результирующем наборе видны 2 причины: 1. Таковы данные, как мы видим в топике (похоже, ошибочные, но весьма показательные) Код: plaintext 1. 2. 3.
2. Размножение в результате слияний по JOIN OUTER . Задача, позволю себе домыслить за автора, состоит в удалении дубликатов по второй причине при сохранении таковых по причине 1. Любой инструмент, действующий на результирующий набор, будь то UNION ALL или SUM( U3.AMOUNT distinct ) или еще подобный, удалит дубликаты независимо от причины, и, значит, не решит задачу. Посему пока что видны 2 направления в сторону решения: а) Принять как постулат, что исходные данные не могут повторяться, и применить к выходному набору вышеуказанные инструменты. б) Писать отдельные запросы (хотя бы в виде подзапросов) по каждому полю. Сугубо ИМХО. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 18:16 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
shalamyansky У дубликатов значений полей в результирующем наборе видны 2 причины: 1. Таковы данные, как мы видим в топике (похоже, ошибочные, но весьма показательные) Код: plaintext 1. 2. 3.
... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 18:28 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Значит, вам подходит решение (а). Добавьте слово distinct в агрегатную функцию, и довольно будет. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 18:34 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1Но чтобы не быть голословным при написании вопроса, создал все базы таблицы Чтобы не быть голословным это надо было делать в https://dbfiddle.uk/?rdbms=firebird_3.0 а сюда постить линк на уже готовые данные. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 18:34 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1 Dimitry Sibiryakov Слишком кривая схема данных, слишком странное требование "одним запросом". Ничего кривого не вижу. Требование простое "отдать всю работу с клиента на сервер", в идеале одним запросом. Симонов Денис Rom1, причём тут GOODS1, если в запросе KreatorXXI он вычитывается ровно один раз. Это к его результатам добавляются результаты 3-х подзапросов Я не знаю как СУБД устроена внутри, возможно будет основной запрос товаров, после идентификаторы сериализуются и передаются в те три запроса, в результате имеем четыре запроса. Может быть и так, я не знаю, пусть эксперты подтвердят. Лично я смотрю "в лоб" и вижу в этом примере, что на каждый товар по три запроса, 1000 товаром, 3000 запросов. Но может это и не так, я же написал - "насколько понимаю". и чего это тебя смущает, проверь и посмотри планы и время выполнения и пользы больше и времени потраченного немного А уж если время выполнения не устроит то и приходи, помогут тут ... |
|||
:
Нравится:
Не нравится:
|
|||
07.10.2021, 18:36 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1 Да, сам уже дошел до такого: Где же дошёл? Union all скорее всего будет невыгодным в Вашем случае. Если как у меня не получается, то есть "Select from select", есть CTE. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.10.2021, 09:53 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
KreatorXXI Где же дошёл?есть CTE. Я имел ввиду "докатился" в опытах. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.10.2021, 16:23 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Всё решил с помощью временной таблицы, в неё отгружаю (update or insert) записи из USAGE N -> GOODSID, sum(AMOUNT) as SUM N В результате получаю время выполнения 2 минуты, против 40-60 встроенными селектами. Ну так как таблица временная, то во время запуска процедуры она будет очищаться, потом заполняться (как описал выше), а это даст хреновую статистику по апдейтам. Что с этим делать, пока не знаю. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2021, 10:50 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1, Как 2 минуты? У Вас миллионы (десятки, сотни) записей? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2021, 14:20 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
KreatorXXI Rom1, Как 2 минуты? У Вас миллионы (десятки, сотни) записей? Дык. Таблицу-то временную ещё ж залить надо. Я бы сделал селективную процедуру с тремя запросами раз уж очень хочется одним клиентским запросом и не парился. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2021, 14:29 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Старый плюшевый мишка, у ТС запрос выполняется 40-60 минут. Что там? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2021, 15:14 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
KreatorXXI Старый плюшевый мишка, у ТС запрос выполняется 40-60 минут. Что там? Хрень какая-то, а какая сказать трудно, он толком ничего не говорит, а что говорит, говорит с ашипками. Но три иннера по-любому уделают этажерку с юнионами. Если с индексами всё боле-мене ;) ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2021, 16:04 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
KreatorXXI Как 2 минуты? У Вас миллионы (десятки, сотни) записей? USAGE N , это не плоские таблицы, там несколько выборок с агрегацией и кучей джойнов, около 3 млн записей на всё. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2021, 07:35 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1 Всё решил с помощью временной таблицы, в неё отгружаю (update or insert) записи из USAGE N -> GOODSID, sum(AMOUNT) as SUM N В результате получаю время выполнения 2 минуты, против 40-60 встроенными селектами. Ну так как таблица временная, то во время запуска процедуры она будет очищаться, потом заполняться (как описал выше), а это даст хреновую статистику по апдейтам. Что с этим делать, пока не знаю. Зачем update or insert, почему-бы не обойтись только insert? Зачем очищать таблицу во время запуска процедуры? (ну разве что в одной транзакции несколько раз будешь её запускать, да и то можно без очистки обойтись) ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2021, 09:26 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
m7m Зачем update or insert, почему-бы не обойтись только insert? Зачем очищать таблицу во время запуска процедуры? (ну разве что в одной транзакции несколько раз будешь её запускать, да и то можно без очистки обойтись) Так товар может и не присутствовать в USAGE 1 , там в SUM1 будет 0. А допустим будет только в USAGE 3 , там в SUM3 будет будет некая сумма всех значений этого товара в выборке. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2021, 12:39 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Наверное не так ответил на ваш вопрос. Перефразирую - во временной таблице через (uppdate or insert) я получаю всего одну запись, в которой будут заполнены все SUM N по GOODSID, а может и не все, но всё равно это будет всего одна запись. А если использовать только инсерты, то я получу по каждому GOODSID от 0 до N SUM's и всё это придется еще агрегировать. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2021, 12:44 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Еще добавлю. Очистка производится один раз, для получения сводных данных по товару, это срез данных на текущий момент, в следующий раз эти данные будут уже не актуальны и всё придется делать с чистого листа. Поэтому это и временная таблица, только для формирования остатков по всем USAGE N ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2021, 12:59 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Почему бы не формировать остатки в реальном времени? Тогда запрос будет выполняться за доли секунды. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2021, 13:11 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov Почему бы не формировать остатки в реальном времени? Тогда запрос будет выполняться за доли секунды. В реальном времени можно это делать по одной единице товара, да и это займет времени совсем чуть, можно даже кешировать результат. Однако мне нужен срез по пулу товаров, и тут всё работало, но не устраивало время выполнения этой операции, потому что перебиралась "руками" каждая единица товара из пула. Это просто вопрос оптимизации. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2021, 13:20 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Эта оптимизация уже давно называется "OLAP" и делается без особых проблем как руками, так и готовыми инструментами. Ничто же не мешает строить куб по твоему "пулу"... Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2021, 13:24 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
В любом случае 3 млн записей за 2 минуты (не говоря о 40-60) - это непозволительно много. Надо оптимизировать или пересматривать запросы совсем. Было бы 3 млрд, можно было бы и о кубах подумать. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2021, 17:48 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1 Dimitry Sibiryakov Почему бы не формировать остатки в реальном времени? Тогда запрос будет выполняться за доли секунды. В реальном времени можно это делать по одной единице товара, да и это займет времени совсем чуть, можно даже кешировать результат. Однако мне нужен срез по пулу товаров, и тут всё работало, но не устраивало время выполнения этой операции, потому что перебиралась "руками" каждая единица товара из пула. Это просто вопрос оптимизации. Мнэээ... Этот срез нужен с точностью до миллисекунды? Помнится, была у меня в обиходе табличка для стратегической и тактической аналитики. Ну там ABC, теория управляемого накопителя, бюджетирование и всё такое. По трём линиям поставки - Европа, Азия и остальной мир, с комплектационными складами на линиях, товарах на них, в пути между ними, в пути от поставщиков, в принятых к исполнению поставщиками заказах, в отправленных поставщикам на утверждение (даты они ещё могли поменять), доходностями, наличием денег в определённых банках, прогнозами их прибытия на основе статистики прошлых лет и тенденций момента, первой и второй производными приходов и расходов и прогнозами состояния запасов в перечисленных стадиях на месяц, два... полгода, ещё чего-то, не помню уже, короче к сотне полей. На фоне сотни тыщ позиций номенклатуры. Пересчитывалась инсёртами с датой (чтобы можно было сравнить свои представления с любым временным интервалом) по ночам часа за три. На серваке сборки 2004 года и FB 1.5. Ну кого в течение дня мнэээ... колыхало, что за день картина ушла на полпроцента? На крайняк для отражения кардинальных судьбоносных изменений по группе товаров был предусмотрен оперативный пересчёт по именно ней. Кеширование, ля... Ещё вопрос имею, чиста для самообразования. Чем временная таблица в срочно-оперативной схеме интересней возврата агрегированных данных в параметрах процедуры, которая их наагрегировала, не беспокоя диск? ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2021, 17:56 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
KreatorXXI В любом случае 3 млн записей за 2 минуты (не говоря о 40-60) - это непозволительно много. Надо оптимизировать или пересматривать запросы совсем. Было бы 3 млрд, можно было бы и о кубах подумать. 9 млн за 40 секунд в 2004 году. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2021, 17:58 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1 m7m Зачем update or insert, почему-бы не обойтись только insert? Зачем очищать таблицу во время запуска процедуры? (ну разве что в одной транзакции несколько раз будешь её запускать, да и то можно без очистки обойтись) Так товар может и не присутствовать в USAGE 1 , там в SUM1 будет 0. А допустим будет только в USAGE 3 , там в SUM3 будет будет некая сумма всех значений этого товара в выборке. Rom1 Наверное не так ответил на ваш вопрос. Перефразирую - во временной таблице через (uppdate or insert) я получаю всего одну запись, в которой будут заполнены все SUM N по GOODSID, а может и не все, но всё равно это будет всего одна запись. А если использовать только инсерты, то я получу по каждому GOODSID от 0 до N SUM's и всё это придется еще агрегировать. Ну так и суммируй их, возможно это лучше чем апдейтить и может быть даже гораздо лучше Rom1 Еще добавлю. Очистка производится один раз, для получения сводных данных по товару, это срез данных на текущий момент, в следующий раз эти данные будут уже не актуальны и всё придется делать с чистого листа. Поэтому это и временная таблица, только для формирования остатков по всем USAGE N ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2021, 08:49 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Задача решена, выполняется быстро. Однако во время перевода в продакт, занимались чисткой лишних индексов и был удален обязательный индекс по GOODSID, во временной таблице. После этого время выполнения снова подскочило до ~1 часа. Отсюда я могу предположить, что вариант, как с временной таблицей, так и с вложенными запросами - одинаково производительны. НО! При вложенном запросах, видимо, необходимо грамотно составлять план, чтобы построились временные индексы. Но я в планах не силён, от слова совсем, поэтому мой вариант - временная таблица. Пишу это потому, что некоторые участники заинтересовались почему может быть такая разница в производительности. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2021, 08:51 |
|
Прошу помощи с JOIN
|
|||
---|---|---|---|
#18+
Rom1 При вложенном запросах, видимо, необходимо грамотно составлять план, чтобы построились временные индексы. Но я в планах не силён, от слова совсем, поэтому мой вариант - временная таблица. Какие такие временные индексы? А планами занимается встроенный планировщик. В Вашем примере достаточно всё просто. Придумали себе проблему. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2021, 10:06 |
|
|
start [/forum/topic.php?all=1&fid=40&tid=1559898]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
28ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
66ms |
get tp. blocked users: |
2ms |
others: | 12ms |
total: | 153ms |
0 / 0 |