Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Прошу помощи с JOIN / 25 сообщений из 44, страница 1 из 2
07.10.2021, 08:25
    #40102531
Rom1
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Есть таблица идентификаторов товаров:
Код: sql
1.
2.
[GOODS]
ID INTEGER;


Содержание:
Код: plaintext
ID = 123

Есть три таблицы, где есть расход по этим товарам:
Код: sql
1.
2.
3.
[USAGE1]
GOODSID INTEGER;
AMOUNT NUMERIC(10,2);


Содержание:
Код: plaintext
GOODSID = 123; AMOUNT = 101

[USAGE2]
Код: sql
1.
2.
GOODSID INTEGER;
AMOUNT NUMERIC(10,2);


Содержание:
Код: plaintext
1.
GOODSID = 123; ABOUNT = 201
GOODSID = 123; ABOUNT = 202

[USAGE3]
Код: sql
1.
2.
GOODSID INTEGER;
AMOUNT NUMERIC(10,2);


Содержание:
Код: plaintext
1.
2.
GOODSID = 123; ABOUNT = 301
GOODSID = 123; ABOUNT = 302
GOODSID = 123; ABOUNT = 301


Нужно одним запросом посчитать суммы по всем трем таблицам:
Код: sql
1.
2.
3.
4.
5.
6.
select G.ID, sum(U1.AMOUNT) SUM1, sum(U2.AMOUNT) SUM2, sum(U3.AMOUNT) SUM3
from GOODS1 G
left outer join USAGE1 U1 on U1.GOODSID = G.ID
left outer join USAGE2 U2 on U2.GOODSID = G.ID
left outer join USAGE3 U3 on U3.GOODSID = G.ID
group by G.ID


Получаю это:
Код: plaintext
1.
ID	SUM1	SUM2	SUM3
123	606	1209	1812

Ну и без группировки это выглядит так:
Код: plaintext
1.
2.
3.
4.
5.
6.
ID	SUM1	SUM2	SUM3
123	101	201	301
123	101	201	302
123	101	201	303
123	101	202	301
123	101	202	302
123	101	202	303

Какой JOIN мне нужно использовать чтобы данные не дублировались?
Сейчас делаю три отдельных запроса, но это очень некрасиво.
...
Рейтинг: 0 / 0
07.10.2021, 09:06
    #40102544
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Rom1, тебе нужен не JOIN, а UNION из SELECT'ов сумм, если хочешь суммы построчно. Если хочешь суммы по столбцам, то нужен один SELECT, у которого значение каждого поля суммы представлено результатом суммирующего SELECT'а.
...
Рейтинг: 0 / 0
07.10.2021, 11:06
    #40102606
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Rom1
Код: plaintext
1.
2.
GOODSID = 123; ABOUNT = 301
GOODSID = 123; ABOUNT = 302
GOODSID = 123; ABOUNT = 301

rdb_dev
тебе нужен не JOIN, а UNION из SELECT'ов сумм

Надеюсь, понимаешь разницу между UNION и UNION ALL?
...
Рейтинг: 0 / 0
07.10.2021, 12:56
    #40102662
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
wadman, ALL, это опция UNION. Возьмёт Reference Manual и разберётся.
...
Рейтинг: 0 / 0
07.10.2021, 12:59
    #40102666
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
не разберётся.
это тестовая задача.
дорога' ложка к обеду.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
07.10.2021, 13:07
    #40102677
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Мимопроходящий, значит в этот раз повезёт тестирующему, а не тестируемому.
Знавал я одного ребятёнка, который после ВУЗа с дипломом программиста пытался устроиться в Корус вообще без знаний, что такое СУБД и чем её едят. Корусу повезло, ребятёнку нет.
...
Рейтинг: 0 / 0
07.10.2021, 16:26
    #40102784
Rom1
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
rdb_dev
Rom1, тебе нужен не JOIN, а UNION.

Но ведь UNION создаёт новую временную таблицу (в MySQL, в Firebrd не знаю), это же даст отрицательный результат производительности?
...
Рейтинг: 0 / 0
07.10.2021, 16:27
    #40102785
Rom1
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Мимопроходящий

не разберётся.
это тестовая задача.
дорога' ложка к обеду.

Молодой человек, с чего вы взяли что я студент?
...
Рейтинг: 0 / 0
07.10.2021, 16:34
    #40102788
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Rom1,

не создаёт он никаких временных таблиц, уж в ФБ точно.
UNION в отличие от UNION ALL требует сортировку для удаления дубликатов и вот тут есть потеря производительности.
...
Рейтинг: 0 / 0
07.10.2021, 16:35
    #40102790
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Симонов Денис
UNION в отличие от UNION ALL требует сортировку для удаления дубликатов и вот тут есть потеря производительности.

Еще хуже, когда плюс потеря данных в некоторых случаях, как выше.
...
Рейтинг: 0 / 0
07.10.2021, 16:38
    #40102792
Rom1
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Хорошо, если я вынесу (вынес) все эти "три" запроса в процедуру (ранее выполнял их на клиенте), а процедура выдаёт агрегированный результат, насколько это может отличаться по производительности по сравнению с UNION?
...
Рейтинг: 0 / 0
07.10.2021, 16:53
    #40102798
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Rom1,

а чем вот такой вариант не подходит?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
select G.ID, 
         ( select sum(U.AMOUNT)
           from USAGE1 U
           where U.GOODSID = G.ID
         ),
         ( select sum(U.AMOUNT)
           from USAGE2 U
           where U.GOODSID = G.ID
         ),
         ( select sum(U.AMOUNT)
           from USAGE3 U
           where U.GOODSID = G.ID
         )
from GOODS1 G
...
Рейтинг: 0 / 0
07.10.2021, 17:03
    #40102803
Rom1
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
KreatorXXI
Rom1,

а чем вот такой вариант не подходит?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
select G.ID, 
         ( select sum(U.AMOUNT)
           from USAGE1 U
           where U.GOODSID = G.ID
         ),
         ( select sum(U.AMOUNT)
           from USAGE2 U
           where U.GOODSID = G.ID
         ),
         ( select sum(U.AMOUNT)
           from USAGE3 U
           where U.GOODSID = G.ID
         )
from GOODS1 G



Да, сам уже дошел до такого:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
select G.ID, U.AMOUNT SUM1, null SUM2, null SUM3
from GOODS1 G
left outer join USAGE1 U on U.ID = G.ID

union all

select G.ID, null, U.AMOUNT, null
from GOODS1 G
left outer join USAGE2 U on U.ID = G.ID

union all

select G.ID, null, null, U.AMOUNT
from GOODS1 G
left outer join USAGE3 U on U.ID = G.ID



Результат:
Код: plaintext
1.
2.
3.
4.
5.
6.
ID	SUM1	SUM2	SUM3
123	101	null	null
123	null	201	null
123	null	202	null
123	null	null	301
123	null	null	302
123	null	null	303

Честно говоря, если встречу такой запрос в коде, решу что его писал наркоман.

"from GOODS" у меня не просто таблица, а ресурсоёмкий запрос по выборке товаров, по которым надо сделать такую агрегацию, поэтому сделать его хочу один раз за запрос. А вот трижды делать его - полный провал.
Как и в вашем примере, если гудсов тысяча, то запросов будет три тысячи, если я правильно понимаю, а это тоже фейл.
...
Рейтинг: 0 / 0
07.10.2021, 17:10
    #40102804
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Rom1с чего вы взяли что я студент?

Слишком кривая схема данных, слишком странное требование "одним запросом".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
07.10.2021, 17:11
    #40102806
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Rom1,

причём тут GOODS1, если в запросе KreatorXXI он вычитывается ровно один раз. Это к его результатам добавляются результаты 3-х подзапросов
...
Рейтинг: 0 / 0
07.10.2021, 17:14
    #40102807
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Rom1,

можно и таким образом сделать:

Код: sql
1.
2.
select G.ID, (select sum(amount) from USAGE1 where GOODSID = G.ID) sum1
from GOODS1 G
...
Рейтинг: 0 / 0
07.10.2021, 17:25
    #40102810
Rom1
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Dimitry Sibiryakov

Слишком кривая схема данных, слишком странное требование "одним запросом".

Ничего кривого не вижу.
Требование простое "отдать всю работу с клиента на сервер", в идеале одним запросом.

Симонов Денис
Rom1,
причём тут GOODS1, если в запросе KreatorXXI он вычитывается ровно один раз. Это к его результатам добавляются результаты 3-х подзапросов

Я не знаю как СУБД устроена внутри, возможно будет основной запрос товаров, после идентификаторы сериализуются и передаются в те три запроса, в результате имеем четыре запроса. Может быть и так, я не знаю, пусть эксперты подтвердят.
Лично я смотрю "в лоб" и вижу в этом примере, что на каждый товар по три запроса, 1000 товаром, 3000 запросов. Но может это и не так, я же написал - "насколько понимаю".

wadman
Rom1,
можно и таким образом сделать:
[/src]

KreatorXXI уже привел подобный пример
...
Рейтинг: 0 / 0
07.10.2021, 17:47
    #40102814
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Rom1Ничего кривого не вижу.

Три разные таблицы с общим назначением "расход" и совершенно одинаковой
структурой. Так БД обычно не делают.

Rom1Требование простое "отдать всю работу с клиента на сервер", в идеале
одним запросом.
Вот этот "идеал" - как раз студенческий уровень. Три простых отдельных запроса
часто быстрее одного хитроподвыподвертнутого.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
07.10.2021, 18:16
    #40102824
shalamyansky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
У дубликатов значений полей в результирующем наборе видны 2 причины:

1. Таковы данные, как мы видим в топике (похоже, ошибочные, но весьма показательные)
Код: plaintext
1.
2.
3.
GOODSID = 123; ABOUNT = 301
GOODSID = 123; ABOUNT = 302
GOODSID = 123; ABOUNT = 301
Значение ABOUNT=301 повторяется два раза.

2. Размножение в результате слияний по JOIN OUTER .

Задача, позволю себе домыслить за автора, состоит в удалении дубликатов по второй причине при сохранении таковых по причине 1.

Любой инструмент, действующий на результирующий набор, будь то UNION ALL или SUM( U3.AMOUNT distinct ) или еще подобный, удалит дубликаты независимо от причины, и, значит, не решит задачу.

Посему пока что видны 2 направления в сторону решения:

а) Принять как постулат, что исходные данные не могут повторяться, и применить к выходному набору вышеуказанные инструменты.

б) Писать отдельные запросы (хотя бы в виде подзапросов) по каждому полю.

Сугубо ИМХО.
...
Рейтинг: 0 / 0
07.10.2021, 18:28
    #40102835
Rom1
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
shalamyansky
У дубликатов значений полей в результирующем наборе видны 2 причины:
1. Таковы данные, как мы видим в топике (похоже, ошибочные, но весьма показательные)
Код: plaintext
1.
2.
3.
GOODSID = 123; ABOUNT = 301
GOODSID = 123; ABOUNT = 302
GOODSID = 123; ABOUNT = 301
Значение ABOUNT=301 повторяется два раза.
Это синтаксическая ошибка в топике, тут синтетические данные же. Но чтобы не быть голословным при написании вопроса, создал все базы таблицы (тут по ошибке GOODS превратилась в GOODS1), но наборы данных уже корректные, я вывод вставлял настоящий.
...
Рейтинг: 0 / 0
07.10.2021, 18:34
    #40102838
shalamyansky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Значит, вам подходит решение (а). Добавьте слово distinct в агрегатную функцию, и довольно будет.
...
Рейтинг: 0 / 0
07.10.2021, 18:34
    #40102839
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Rom1Но чтобы не быть голословным при написании вопроса, создал все базы таблицы

Чтобы не быть голословным это надо было делать в
https://dbfiddle.uk/?rdbms=firebird_3.0 а сюда постить линк на уже готовые данные.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
07.10.2021, 18:36
    #40102841
m7m
m7m
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Rom1
Dimitry Sibiryakov

Слишком кривая схема данных, слишком странное требование "одним запросом".

Ничего кривого не вижу.
Требование простое "отдать всю работу с клиента на сервер", в идеале одним запросом.

Симонов Денис
Rom1,
причём тут GOODS1, если в запросе KreatorXXI он вычитывается ровно один раз. Это к его результатам добавляются результаты 3-х подзапросов

Я не знаю как СУБД устроена внутри, возможно будет основной запрос товаров, после идентификаторы сериализуются и передаются в те три запроса, в результате имеем четыре запроса. Может быть и так, я не знаю, пусть эксперты подтвердят.
Лично я смотрю "в лоб" и вижу в этом примере, что на каждый товар по три запроса, 1000 товаром, 3000 запросов. Но может это и не так, я же написал - "насколько понимаю".

и чего это тебя смущает, проверь и посмотри планы и время выполнения
и пользы больше и времени потраченного немного
А уж если время выполнения не устроит то и приходи, помогут тут
...
Рейтинг: 0 / 0
08.10.2021, 09:53
    #40102955
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
Rom1

Да, сам уже дошел до такого:


Где же дошёл? Union all скорее всего будет невыгодным в Вашем случае. Если как у меня не получается, то есть "Select from select", есть CTE.
...
Рейтинг: 0 / 0
08.10.2021, 16:23
    #40103114
Rom1
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи с JOIN
KreatorXXI

Где же дошёл?есть CTE.

Я имел ввиду "докатился" в опытах.
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Прошу помощи с JOIN / 25 сообщений из 44, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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