|
|
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
Добрейшего времени суток! В результате составления запроса на очередную форму отчетности - получается не совсем красивая конструкция. Хотелось бы ее как-то оптимизировать. Приведу "синтетический" пример: Код: plsql 1. 2. 3. 4. 5. Результат: Код: sql 1. 2. 3. 4. 5. 6. 7. Но таких кэйзов 37 блоков, в каждом блоке 25 штук. Хотелось бы сократить в нечто подобное ниже, но это не работает. Вернее выполняется успешно, но результат не тот, что нужен: Код: plsql 1. 2. 3. Иными словами, можно ли одним кейзом генерировать несколько полей сразу? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2015, 17:54 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
Majestio, Нужны именно раздельные поля? Вместо 37х25 кейзов можно применить 37 джоинов на 25 полей. Но такая эстетика субъективна, а вот ресурсов может съесть чуть больше. Код: sql 1. 2. 3. 4. Если нужна именно *, то coalesce на каждое поле или уже накручивать lateral c union по Idx. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2015, 18:30 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
Нужны именно кейзы, ибо внутри них сплошные агрегатные функции от запроса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2015, 18:34 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
Опубликую сырой вид запроса, чтобы было понятно о чем речь: Код: 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. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. В запросе используется функция: Код: 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. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. Собственно, с этим и воюю :-\ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2015, 18:53 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
SELECT '1111' AS case1, '2222' AS case2, '3333' AS case3 UNION ALL SELECT '*', '*', '*' FROM generate_series(1,3); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2015, 18:55 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
MajestioОпубликуютебя же не смущает бесполезный COALESCE(pr1."Rubrica",0) в равенстве с ненулевой константой. Если лень набирать буквы case ... else 0 end, замени на умножение на условие, приведенное к integer. А во внутреннем запросе и умножение не нужно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2015, 19:08 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
dmikelios , это не прокатит - только если для воспроизведения "синтетического" примера, и то с ошибкой (1 лишняя строка). Я выше опубликовал набросок запроса, посмотри, плс, как там все начинается и че с этим можно сделать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2015, 19:08 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
p2.MajestioОпубликуютебя же не смущает бесполезный COALESCE(pr1."Rubrica",0) в равенстве с ненулевой константой. Оффтоп. Речь не об этом. И да, не смущает. В данном случая оптимизатор отрабатывает на отлично, а мне копипастить удобнее. Для примера ... Этот запрос: Код: plsql 1. 2. 3. 4. 5. 6. И этот запрос: Код: plsql 1. 2. 3. 4. 5. 6. По эксплайну строго идентичны: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. Поэтому давай по теме попробуем продолжить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2015, 19:21 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
Majestio, Ваша проблема разобрана например тут http://www.postgresql.org/message-id/flat/CAMr3DCMJfbxFAK08rpOZSoGKNMCA+fM+YO6X=RkTeczrX_8sLQ@mail.gmail.com#CAMr3DCMJfbxFAK08rpOZSoGKNMCA+fM+YO6X=RkTeczrX_8sLQ@mail.gmail.com]http://www.postgresql.org/message-id/flat/CAMr3DCMJfbxFAK08rpOZSoGKNMCA fM YO6X=RkTeczrX_8sLQ@mail.gmail.com#CAMr3DCMJfbxFAK08rpOZSoGKNMCA fM YO6X=RkTeczrX_8sLQ@mail.gmail.com Я бы посоветовал делать через регистрацию кастомного типа. Это самый прямой метод для вашей задачи. Как то так: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. -- Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2015, 19:30 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
Maxim, спасибо! Попробую поэкспериментировать, посмотрю на сколько станет удобнее и быстрее/медленнее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2015, 19:42 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
Majestio, Если использовать CTE и UNION, то можно избавиться от CASE-ов, но, наверное, будет работать медленнее, чем в Вашем исходном варианте. WITH x2 AS (SELECT x."FamilyId", SUM(x."x03") AS "x03", SUM(x."x01") AS "x01", ..., SUM(x."r22") AS "r22" FROM (...) AS x GROUP BY x."FamilyId" ) SELECT x2."FamilyId", 1 AS "Z01-AA", x2."x01" AS "Z01-BB", ..., x2."r22" AS "Z01-42" FROM x2 WHERE x2."x03" > 2 UNION ALL SELECT x2."FamilyId", 0 AS "Z01-AA", 0 AS "Z01-BB", ..., 0 AS "Z01-42" FROM x2 WHERE x2."x03" <= 2; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2015, 20:13 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
MajestioПо эксплайну строго идентичныТо, что в плане синтетического запроса не отражена стоимость скалярных выражений, никак не дает понимания целей изысков. В начальной постановке озвучена эстетическая цель. По этому критерию лишние символы Код: sql 1. противоречат моим представлениям. И с точностью до null заменимо на Код: sql 1. так как далее интерпретируется только true/1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2015, 20:14 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
-2-так как далее интерпретируется только true/1. Мне не нужны NULL'и в промежуточном результате. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.08.2015, 02:37 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
Majestio, Добрый день. MajestioВ результате составления запроса на очередную форму отчетности - получается не совсем красивая конструкция. Хотелось бы ее как-то оптимизировать. ИМХО. Делайте отчетность на OLAP кубах и будет вам счастье. Как вариант Postgresql + Pentaho (ROLAP). С уважением, biwed.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.08.2015, 03:19 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
biwed.ruИМХО. Делайте отчетность на OLAP кубах и будет вам счастье. Спасибо за совет. Бегло посмотрел - интересно. Но пока, увы, проект горит - последний отчет доделываю и на сдачу. Нет времени для освоения и внедрения "на лету". biwed.ruКак вариант Postgresql + Pentaho (ROLAP) Посмотрел Pentaho. Возможно продукт хороший, но увы, платный. Я же в своей работе всегда пользуюсь исключительно бесплатными решениями: сервер как правило FreeBSD, реже линух, DB - pgsql, клиентские части - Qt5 некоммерческая лицензия. Но идею понял, попробую найти из OLAP что-то более другое, бесплатное. Еще раз спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.08.2015, 04:02 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
MajestioПосмотрел Pentaho. Возможно продукт хороший, но увы, платный. Я же в своей работе всегда пользуюсь исключительно бесплатными решениями: сервер как правило FreeBSD, реже линух, DB - pgsql, клиентские части - Qt5 некоммерческая лицензия. Но идею понял, попробую найти из OLAP что-то более другое, бесплатное. Еще раз спасибо. Вроде бы у Pentaho есть бесплатная версия. А так, сам Pentaho сделан на свободном движке Mordrian. Так что если есть желание попрограммировать, то можно взять Mordrian. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.08.2015, 06:31 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
Majestio, Добрый день. MajestioПосмотрел Pentaho. Возможно продукт хороший, но увы, платный. Я же в своей работе всегда пользуюсь исключительно бесплатными решениями: сервер как правило FreeBSD, реже линух, DB - pgsql, клиентские части - Qt5 некоммерческая лицензия. Но идею понял, попробую найти из OLAP что-то более другое, бесплатное. Еще раз спасибо. Это вы не погуглили даже. Есть Pentaho CE (Community Edition) http://community.pentaho.com/ Более подробно тут в этом топике: http://www.sql.ru/forum/1086007/kto-nibud-polzuet-pentaho PS. Сам работаю на стеке Pentaho CE + PostgreSQL. С уважением, biwed.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.08.2015, 08:25 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
1. т.к. ф-я у вас security invoker -- переделайте её на language sql 2 я бы все же вынес агрегирование в подзапрос|cte, а case -ы исчислял уже над результатами -- т.к. у вас всё равно всё агрегируется до разбора кейсов. Вероятно оптимайзер с этим справляется и сам [отождествляя одинаковые агрегаты] -- но зачем его напрягать лишним разбором. [А если не справляется -- у вас кучи подсчетов дублей агрегатов.] а вот что меньше всего бы меня беспокоило -- так это лаконичность выражения. нужна легко оптимизируемая, а не лаконичная декларация. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.08.2015, 10:51 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
qwwq1. т.к. ф-я у вас security invoker -- переделайте её на language sql 2 я бы все же вынес агрегирование в подзапрос|cte, а case -ы исчислял уже над результатами -- т.к. у вас всё равно всё агрегируется до разбора кейсов. Вероятно оптимайзер с этим справляется и сам [отождествляя одинаковые агрегаты] -- но зачем его напрягать лишним разбором. [А если не справляется -- у вас кучи подсчетов дублей агрегатов.] а вот что меньше всего бы меня беспокоило -- так это лаконичность выражения. нужна легко оптимизируемая, а не лаконичная декларация. Вы правы. Но время уж сильно торопит, надо сдаваться - оптимизировать некогда. Да и запрос, по скорости выполнения, пока устраивает - на 3000 записях в двух основных таблицах отрабатывает примерно 1-1.5 сек. Это приемлемо, ожидается 500-1000 записей в год. Сдамся, потом посмотрю в сторону оптимизации. А пока взял да и написал на Perl'е скрипт, который догенерил мне SQL запрос. Увы, сюда не могу вставить - форум говорит 100кб максимум на сообщение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2015, 07:52 |
|
||
|
CASE WHEN с множеством полей
|
|||
|---|---|---|---|
|
#18+
biwed.ruЭто вы не погуглили даже. Есть Pentaho CE (Community Edition) http://community.pentaho.com/ Более подробно тут в этом топике: http://www.sql.ru/forum/1086007/kto-nibud-polzuet-pentaho Спасибо. Взял на заметочку. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2015, 07:59 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=39022889&tid=1997839]: |
0ms |
get settings: |
8ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
179ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
| others: | 214ms |
| total: | 483ms |

| 0 / 0 |
