Как выполнить несколько вычислений в двух столбцах для заданного первичного ключа - PullRequest
1 голос
/ 08 июля 2019

Запрос редактируется в соответствии с просьбой других участников. Заранее большое спасибо. Для данного первичного ключа (id_pk) предположим следующие значения:

 1. id_pk | code_col| amt_col
 2. abc   | 10  | 1000
 3. abc   | 11  | 5
 4. abc   | 12  | 10
 5. abc   | 13  | 20

Теперь мне нужно проверить, существует ли для данного первичного ключа с именем «abc» значение с именем «10» в столбце «code_col». Если это условие удовлетворяется, то необходимо выполнить следующее:

  1. Для того же первичного ключа abc, для значения code_col, равного 11, вычтите значение amt_col (т.е. 5) из значения amt_col, равного 10 (то есть 1000). Таким образом, конечное значение 0 должно быть обновлено во второй строке таблицы выше.
  2. Для того же первичного ключа abc, для значения code_col, равного 12, вычтите значение amt_col (т.е. 10) из значения amt_col, равного 10 (то есть, 1000). Таким образом, конечное значение 0 должно быть обновлено в третьей строке таблицы выше.
  3. Для того же первичного ключа abc, для значения code_col, равного 13, вычтите значение amt_col (т.е. 20) из значения amt_col, равного 10 (то есть, 1000). Таким образом, окончательное значение -865 (оставшиеся) должно быть обновлено в четвертой / последней строке таблицы выше.

Результаты должны быть такими, как показано ниже:

 1. id_pk | col1| col2
 2. abc   | 10  | 0
 3. abc   | 11  | 0
 4. abc   | 12  | 0
 5. abc   | 13  | -965

Надеюсь, это понятно. Мне нужно добиться этой проверки в Teradata (Query / Cursor / StoredProcedure / macros / все остальное также приветствуется.

Если тексты выделены жирным шрифтом, скопируйте и вставьте содержимое в Блокнот ++, как я использовал для публикации здесь.

Ответы [ 3 ]

0 голосов
/ 09 июля 2019

Это, кажется, соответствует вашим требованиям:

SELECT id_pk, code_col
  ,CASE
     WHEN code_col = Max(code_col) Over (PARTITION BY id_pk) -- "last" row?
     THEN -- negative code 10 amount
       Max(CASE WHEN code_col = 10 THEN -amt_col*2 end) Over (PARTITION BY id_pk)
          --  plus the sum of all other amounts
       + Sum(amt_col) Over (PARTITION BY id_pk)
     ELSE 0
   END
FROM tab
QUALIFY -- only ids with a code 10
   Max(CASE WHEN code_col = 10 THEN code_col end) Over (PARTITION BY id_pk) = 10
0 голосов
/ 09 июля 2019

Это общая логика, которую вы можете преобразовать в синтаксис Teradata.

SELECT id_pk,
code_col col1,
CASE 
    WHEN code_col = 13 THEN (Sum_10 - Sum_Other)
    ELSE 0
END col2
FROM your_table A
LEFT JOIN
(
    SELECT id_pk, 
    SUM(CASE WHEN code_col = 10 THEN amt_col ELSE NULL END) Sum_10,
    SUM(CASE WHEN code_col <> 10 THEN amt_col ELSE NULL END) Sum_Other 
    FROM your_table
    GROUP BY id_pk
)B ON A.id_pk = B.id_pk

В качестве альтернативы, вы также можете попробовать эту логику ниже -

SELECT 
A.id_pk,
A.code_col col1,
CASE 
    WHEN A.code_col = 13 THEN
        (SELECT amt_col FROM your_table WHERE code_col = 10 AND id_pk = A.id_pk)
        -
        (SELECT SUM(amt_col) FROM your_table WHERE code_col <> 10 AND id_pk = A.id_pk)
    ELSE 0
END col2
FROM your_table A
0 голосов
/ 08 июля 2019

Так как здесь есть некоторая двусмысленность (откуда берется 1000), (Зачем пропускать первую запись?) И т. Д ... вот быстрый удар по кумулятивной сумме, которая приводит вас в стадион:

SELECT id_pk, 
    col1, 
    0 AS col2, 
    -1000 + SUM(SUM(col2)) OVER (PARTITION BY id_pk ORDER BY col1 ROWS UNBOUNDED PRECEDING) AS col3
FROM t1
GROUP BY id_pk, col1, col2
...