I have below table
WITH TMP AS (
SELECT 'XX' AS AGG, 50 AS VALUE, 0 AS MONTH
UNION ALL
SELECT 'XX' AS AGG, 150 AS VALUE, 1 AS MONTH
UNION ALL
SELECT 'XX' AS AGG, 300 AS VALUE, 2 AS MONTH
UNION ALL
SELECT 'YY' AS AGG, 25 AS VALUE, 0 AS MONTH
UNION ALL
SELECT 'YY' AS AGG, 50 AS VALUE, 1 AS MONTH
UNION ALL
SELECT 'YY' AS AGG, 75 AS VALUE, 2 AS MONTH
UNION ALL
SELECT 'ZZ' AS AGG, 500 AS VALUE, 0 AS MONTH
UNION ALL
SELECT 'ZZ' AS AGG, 600 AS VALUE, 1 AS MONTH
UNION ALL
SELECT 'ZZ' AS AGG, 700 AS VALUE, 2 AS MONTH
)
-- CASE WHEN VALUE OF 'XX' > 0 THEN VALUE OF 'ZZ' ELSE 0 END
SELECT
*
FROM TMP
WHERE 1 = 1
I need to apply following business logic to it always considering the month.
CASE WHEN VALUE OF 'XX' > 0 THEN VALUE OF 'ZZ' ELSE 0 END
This logic should be mapped into a new table. The result should look like the table below.
I would like to avoid joins to the same table. Is this somehow possible using window functions or something similar? The idea is to build several case when statement as the one above within the same sql statement.
IE1 | MONTH |
---|---|
500 | 00 |
600 | 01 |
700 | 02 |
CodePudding user response:
Pivot (conditionally aggregate) your data, and then return the value you need based on your expression:
WITH TMP AS
(SELECT 'XX' AS AGG,
50 AS VALUE,
0 AS MONTH
UNION ALL
SELECT 'XX' AS AGG,
150 AS VALUE,
1 AS MONTH
UNION ALL
SELECT 'XX' AS AGG,
300 AS VALUE,
2 AS MONTH
UNION ALL
SELECT 'YY' AS AGG,
25 AS VALUE,
0 AS MONTH
UNION ALL
SELECT 'YY' AS AGG,
50 AS VALUE,
1 AS MONTH
UNION ALL
SELECT 'YY' AS AGG,
75 AS VALUE,
2 AS MONTH
UNION ALL
SELECT 'ZZ' AS AGG,
500 AS VALUE,
0 AS MONTH
UNION ALL
SELECT 'ZZ' AS AGG,
600 AS VALUE,
1 AS MONTH
UNION ALL
SELECT 'ZZ' AS AGG,
700 AS VALUE,
2 AS MONTH),
--Solution
/*WITH */Pvt AS(
SELECT Month,
MAX(CASE Agg WHEN 'XX' THEN VALUE END) AS XX,
--MAX(CASE Agg WHEN 'YY' THEN VALUE END) AS YY,--Not needed hence commented out
MAX(CASE Agg WHEN 'ZZ' THEN VALUE END) AS ZZ
FROM TMP
GROUP BY MONTH)
SELECT CASE WHEN XX > 0 THEN ZZ ELSE 0 END AS IE1,
MONTH
FROM Pvt;