|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Имеется такой запрос (упрощенный для примера): Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
Задача: выбрать по каждому контрагенту ( c.id ) в доме ( mkd ) некоторую информацию из data_sgrc , присовокупив к выборке данные еще из нескольких таблиц по контрагенту. Все работает хорошо до тех пор, пока в таблице test не появилось несколько записей на одного контрагента и их все надо выбрать. Получается вот так: Т.е. дублирование данных на каждую добавленную запись из test . Как можно этого избежать? Т.е. чтобы вместо данных в красной рамке было Null. Дополнительно: в таблице notifications всегда только одна запись на контрагента, но в claims также может быть несколько записей на одного контрагента (в примере - одна). ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2020, 11:43 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
LiYing, Сгруппировать данные в test у тебя будет одна запись на 1 c.id А вообще всё плохо, я только запрос увидел и уже захотелось выпить. Присовокупляй данные как-нибудь отдельно, а не всё в одной куче. Раньше я делал такое с помошью inmemory таблицы и update, а сейчас делаю на промежуточном слое. Волосы стали мягкими и шелковистыми, бросил пить, вернулась жена. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2020, 11:57 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
crutchmaster Сгруппировать данные в test у тебя будет одна запись на 1 c.id Нужно как раз 4 записи из test (на c.id=9884) и столько, сколько есть из notifications , claims . ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2020, 13:08 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Если дублирующиеся данные из первых двух столбцов нельзя за-null-ить, то может это можно сделать хотя бы для дубликатов из notifications , claims ? Чтобы стало так: ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2020, 15:31 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Версию MySQL принципиально не указываем? а зря - на ЭТОЙ задаче версия не просто важна, а критична. А так - да, решаемо. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2020, 15:34 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Akina, Извиняюсь, упустил сей момент. Версия 8.0.13 ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2020, 15:41 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Если точно так же упрощённо - то Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
c.id я всё же оставил. И думаю, что его не надо удалять хотя бы для контроля. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2020, 15:45 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
LiYing Версия 8.0.13 Тогда можно не использовать переменные: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2020, 15:58 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Akina, Оба варианта работают как хотелось, спасибо! Записал так пример: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
Я правильно понимаю, что если в claims будет несколько записей на одного контрагента, а в test одна или ни одной, то и Код: sql 1.
в селекте нужно обернуть в CASE? ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2020, 16:13 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
В CASE НЕ оборачиваются все выражения, в которых присутствует хотя бы одно поле из таблицы, в которой есть дубликаты. Все остальные - в выражениях которых есть только поля из таблиц с гарантированно одной записью,- оборачиваются в CASE, за исключением одного идентифицирующего поля. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.01.2020, 07:45 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Akina, Понял, спасибо! ... |
|||
:
Нравится:
Не нравится:
|
|||
16.01.2020, 08:29 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Что-то не так получается... Добавил в запрос тестовую таблицу testx , теперь на одного контрагента c.id=9884 приходится 1 запись из notifications , 3 записи из testx и 4 записи из test : Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
Получается такой результат: Появился мультипликативный эффект: 3*4=12 строк на c.id=9884 вместо требуемых четырех. Что делать? :) ... |
|||
:
Нравится:
Не нравится:
|
|||
16.01.2020, 10:17 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
LiYing Что делать? Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
... |
|||
:
Нравится:
Не нравится:
|
|||
16.01.2020, 11:45 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Akina, Нет, не выходит, как только не мучил... Если так Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
то результат такой же как и выше: А если же все завернуть в CASE Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
то опять не то: Еще варианты? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.01.2020, 13:43 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
LiYing Еще варианты? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.01.2020, 15:19 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Akina, Создал fiddle , немного упростив. Хочется видеть для c.id=9884 четыре строки (а не 12 как получается), как нафотошопил тут: ... |
|||
:
Нравится:
Не нравится:
|
|||
16.01.2020, 16:43 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Эээ... это будет совсем другая технология! это ни разу не джойн в лоб, как у тебя. Получается вот такой монстр: Код: sql 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. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48.
fiddle Впрочем, если разобраться, что делает каждая отдельная CTE, то всё довольно просто. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.01.2020, 20:10 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Akina, Чую, завтра весь день уйдет на понимание, спасибо :) А учитывая, что это был нормально так упрощенный от реального пример, иэххх!... ... |
|||
:
Нравится:
Не нравится:
|
|||
16.01.2020, 20:38 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
LiYing завтра весь день уйдет на понимание Главная во всём тонкость - перенос отборов в CTE, который нужно делать достаточно аккуратно. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.01.2020, 20:53 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Akina, Для кого фигня, а для кого и "шарики за ролики" :) Пытаюсь разобраться в запросе, так вроде по раздельности эти CTE понятны, но есть вопросы :) 1) почему в cte_n используется ORDER BY period, а не ORDER BY date_from ? Опечатка? 2) в текущем виде выборка по всем контрагентам за период, а не соображу как теперь сделать выборку по контрагентам в заданном МКД (m.id=152) за период? Т.е. то, что в моем запросе в первом посте записано как Код: sql 1. 2. 3. 4.
Куда это условие вставлять? Добавил в fiddle табличку `mkd` ... |
|||
:
Нравится:
Не нравится:
|
|||
17.01.2020, 09:53 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
LiYing почему в cte_n используется ORDER BY period, а не ORDER BY date_from ? LiYing как теперь сделать выборку по контрагентам в заданном МКД (m.id=152) К тому же у тебя все контрагенты имеют этот МКД - так что на этих данных ты разницу не увидишь. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.01.2020, 12:08 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Akina А просто добавить AND c.id_mkd = 152 в финальный запрос - не устраивает? Оно бы устраивало, если бы работало :) Я чуть изменил в fiddle запрос cte_c и финальный, но споткнулся на ошибке "The used SELECT statements have a different number of columns", т.к. не могу добавить id_mkd в cte_2 из-за того, что используемые в cte_1 CTE ничего не знают о таблице mkd . Запутался вконец... AkinaК тому же у тебя все контрагенты имеют этот МКД - так что на этих данных ты разницу не увидишь. Ну пример просто краткий, не стал сотни записей добавлять, чтобы не загромождать фиддл. Ну предположим, там несколько сотен записей, а не 3. И на каждый id_mkd имеется по сотне контрагентов c.id. Как тогда? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.01.2020, 13:05 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
LiYing не могу добавить id_mkd в cte_2 из-за того, что используемые в cte_1 CTE ничего не знают о таблице mkd ... |
|||
:
Нравится:
Не нравится:
|
|||
17.01.2020, 14:28 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
AkinaА нафига они там? Может и не нафига, но как тогда или устранить ошибку в последнем фиддле или изменить его так, чтобы выбирать данные только по контрагентам из одного заданного МКД? Посмотрите фиддл, плиз. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.01.2020, 15:07 |
|
Совет по JOIN
|
|||
---|---|---|---|
#18+
Вроде разобрался как выбрать контрагентов только из нужного МКД, добавил WHERE id_mkd=152, благо больше никакие данные из таблицы mkd не нужны: Код: sql 1. 2. 3. 4. 5. 6.
Норм решение? Но тут другая бяда выяснилась :) Отбираются все контрагенты по МКД, но нужно только тех, кто присутствует в таблице data в указанный период. С этим-то как быть? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.01.2020, 16:53 |
|
|
start [/forum/topic.php?fid=47&msg=39914389&tid=1828779]: |
0ms |
get settings: |
9ms |
get forum list: |
11ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
91ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
62ms |
get tp. blocked users: |
1ms |
others: | 13ms |
total: | 204ms |
0 / 0 |