|
Задачка SQL: сохранить всю левую таблицу при уникальности связи
|
|||
---|---|---|---|
#18+
У меня есть некие таблицы, из которых надо сделать выборку, соединив их нечёткой связью, но при этом сохранить уникальность. То есть при множестве подходящих под критерий строк из левой и правой таблицы выбирать только по одной. При этом левая таблица должна быть выбрана вся полностью. Всё это на оракле 11g. Для простоты представим, что Маша, Вася и Петя зовут людей в магазин, но когда человек приходит, бонус за это мы даём только Маше, потому что она первая позвала, но знать, что Вася и Петя работали, тоже надо. Не слишком долго думая, я запилил такое Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30.
что вполне удовлетворяет критериям, но тормозит на реальных данных. Вопрос: Нельзя ли обойтись без верхнего левого джойна или может есть другое интересное решение? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.10.2020, 11:23 |
|
Задачка SQL: сохранить всю левую таблицу при уникальности связи
|
|||
---|---|---|---|
#18+
тормозит на реальных данных Оптимизацию начинают с плана. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.10.2020, 12:16 |
|
Задачка SQL: сохранить всю левую таблицу при уникальности связи
|
|||
---|---|---|---|
#18+
Larr`, Если я правильно понял условие: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25.
... |
|||
:
Нравится:
Не нравится:
|
|||
03.10.2020, 12:32 |
|
Задачка SQL: сохранить всю левую таблицу при уникальности связи
|
|||
---|---|---|---|
#18+
dmdmdm Оптимизацию начинают с плана. Начинать с логики получения результата все же лучше, можно долго оптимизировать процесс чесания левого уха правой пяткой, но левой рукой по любому сподручнее. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.10.2020, 12:35 |
|
Задачка SQL: сохранить всю левую таблицу при уникальности связи
|
|||
---|---|---|---|
#18+
graycode, спасибо, интересное решение, но суть в том, что я, похоже, чрезмерно упростил пример Там нельзя взять минимальную дату и получить уникальный набор по b, потому что одна дата зависит от другой. То есть на самом деле условие соединения не a.dt=b.dt , а b.dt between a.dt and a.dt+3 . Мой вариант даёт правильно, а ваш - дублит В 12-ом оракле я бы пропихнул условие и соединил outer apply, а что делать в 11, ума не приложу ... |
|||
:
Нравится:
Не нравится:
|
|||
03.10.2020, 18:11 |
|
Задачка SQL: сохранить всю левую таблицу при уникальности связи
|
|||
---|---|---|---|
#18+
Larr`, Вариант "в лоб": Код: plsql 1. 2. 3. 4. 5. 6. 7. 8.
Вариант втащить a.dt в b: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
... |
|||
:
Нравится:
Не нравится:
|
|||
03.10.2020, 20:41 |
|
Задачка SQL: сохранить всю левую таблицу при уникальности связи
|
|||
---|---|---|---|
#18+
Larr` Вопрос: Нельзя ли обойтись без верхнего левого джойна или может есть другое интересное решение? Можно обойтись Код: plsql 1. 2. 3. 4. 5. 6. 7. 8.
Только внутренний left join дает полупроизведение и основная проблема думаю кроется именно в этом, посмотрите сколько строк в таблице a и сколько строк дает a left join b on b.dt between a.dt and a.dt + 3 . ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2020, 00:00 |
|
Задачка SQL: сохранить всю левую таблицу при уникальности связи
|
|||
---|---|---|---|
#18+
На мой взгляд в задаче не хватает связи "позванных" с "позвавшими". Это приводит к декартову произведению между наборами. От того и тормозит на реальных данных. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2020, 15:12 |
|
Задачка SQL: сохранить всю левую таблицу при уникальности связи
|
|||
---|---|---|---|
#18+
graycode Можно обойтись Код: plsql 1. 2. 3. 4. 5. 6. 7. 8.
Только внутренний left join дает полупроизведение и основная проблема думаю кроется именно в этом, посмотрите сколько строк в таблице a и сколько строк дает a left join b on b.dt between a.dt and a.dt + 3 . Вот, это то, что нужно! Нет, на самом деле, конечно, проблема кроется в том, что оракл пробегает по всем секциям таблицы b, секционированной по dt вместо того, чтобы ограничиться dt из a. С этим разобраться легко. Но поскольку я небольшой начальник и ревьюер кода и всем джуниорам раздаю "сокровенную мудрость" вроде "используй таблицы в джойнах так редко как сможешь" или "самоджойн в эру оконных функций от лукавого", то вот хотелось джуниору, который принёс мне эту функцию сделанную тремя запросами, показать эталон, но оказалось, что SQL потихоньку я стал забывать :) Бельфя На мой взгляд в задаче не хватает связи "позванных" с "позвавшими". Это приводит к декартову произведению между наборами. От того и тормозит на реальных данных. Насколько я помню, раньше каждая маша-зазывала давала клиенту свой промокод на скидку, который он вводил/говорил, но ушлые продавцы на местах слишком часто забивают её скидку своей. Я бизнесу попредлагал вариантов, пусть думают, но премии-то давать уже надо сейчас ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2020, 23:30 |
|
|
start [/forum/topic.php?fid=52&msg=40005106&tid=1880833]: |
0ms |
get settings: |
8ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
37ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
43ms |
get tp. blocked users: |
1ms |
others: | 322ms |
total: | 445ms |
0 / 0 |