Я часто сталкивался с ситуацией, когда я хотел ограничить действие аналитической функции (или OLAP в DB2) определенным подмножеством данных. Вот пример:DB2 ограничивает аналитическую функцию для подзапроса
WITH MY_TABLE AS
(
SELECT 1 AS FIELD1, 'A' AS FIELD2, 1 AS FIELD3, 'X' AS FIELD4 FROM DUAL
UNION
SELECT 1 AS FIELD1, 'A' AS FIELD2, 2 AS FIELD3, 'Y' AS FIELD4 FROM DUAL
UNION
SELECT 1 AS FIELD1, 'B' AS FIELD2, 3 AS FIELD3, 'X' AS FIELD4 FROM DUAL
UNION
SELECT 1 AS FIELD1, 'A' AS FIELD2, 4 AS FIELD3, 'Z' AS FIELD4 FROM DUAL
UNION
SELECT 1 AS FIELD1, 'B' AS FIELD2, 5 AS FIELD3, 'Z' AS FIELD4 FROM DUAL
//...
)
SELECT FIRST_VALUE(FIELD4) OVER (PARTITION BY FIELD1 ORDER BY FIELD3) AS FIELD2_A
FROM MY_TABLE
WHERE FIELD2='A' // need that as well for 'B', 'C' etc.
Теперь громоздкий, чтобы сделать это для всех требуемых значений FIELD2
и после этого делать JOIN или UNION, кроме того, поскольку ограничения могут быть более сложными.
Таким образом, я действительно хочу обрабатывать его в одном SELECT. Вот это испытание:
//...
SELECT CASE WHEN FIELD2 = 'A'
THEN FIRST_VALUE(FIELD4)
OVER (PARTITION BY FIELD1
ORDER BY CASE WHEN FIELD2='A' THEN 0 ELSE 1 END, FIELD3)
ELSE NULL END AS FIELD4_A,
CASE WHEN FIELD2 = 'B'
THEN FIRST_VALUE(FIELD4)
OVER (PARTITION BY FIELD1
ORDER BY CASE WHEN FIELD2='B' THEN 0 ELSE 1 END, FIELD3)
ELSE NULL END AS FIELD4_B,
//a bit more complicated
CASE WHEN FIELD2 IN ('A','C')
THEN FIRST_VALUE(FIELD4)
OVER (PARTITION BY FIELD1
ORDER BY CASE WHEN FIELD2 IN ('A','C') THEN 0 ELSE 1 END, FIELD3)
ELSE NULL END AS FIELD4_AC
FROM MY_TABLE
Идея заключается в том, чтобы упорядочить данные, установленные WHERE-критерию, но так как там могут быть случаи, когда строки с таким ограничением не существуют в перегородке (и, таким образом, нежелательный результат будет получено), ненулевое значение возвращается только в том случае, если FIELD2
соответствует ограничению (это делается во внешнем операторе CASE
).
Я предполагаю, что этот подход работает (- я еще не проверял его), но он немного сложен. Существуют ли более простые или более прямые подходы к выполнению вышеуказанной задачи?
Пожалуйста, измените свой вопрос и добавить примеры данных и желаемые результаты. –