使用 case when

时间:2021-04-11 14:42:17

标签: sql postgresql

以下是基于对 entry_date 的过滤来标记并仅允许少数 ID 的查询:

SELECT A.ID_NO,A.CATEGORY,
CASE WHEN 
(SELECT * FROM NEW_TEST B 
WHERE CATEGORY IN ('ODS','L')
) 
THEN 'ALLOW'
ELSE 'DENY'
END AS NEW_COL
FROM NEW_TEST A;

但是这个查询出错了,有没有办法使用窗口函数或任何其他方法

2 个答案:

答案 0 :(得分:1)

认为您真的想知道每个 ID 和日期是否有 ODS 和 L 类别的三行。如果是这样:

SELECT A.ID_NO, A.ENTRY_DATE, A.CATEGORY,
       (CASE WHEN SUM(CASE WHEN CATEGORY IN ('ODS', 'L') THEN 1 ELSE 0 END) OVER (PARTITION BY ID_NO, ENTRY_DATE) < 3
             THEN 'ALLOW' ELSE 'DENY'
        END) as NEW_COL
FROM NEW_TEST A;

但是,您的代码正在独立检查每个类别,即:

SELECT A.ID_NO, A.ENTRY_DATE, A.CATEGORY,
       (CASE WHEN SUM(CASE WHEN CATEGORY = 'ODS' THEN 1 ELSE 0 END) OVER (PARTITION BY ID_NO, ENTRY_DATE) < 3 OR
                  SUM(CASE WHEN CATEGORY = 'L' THEN 1 ELSE 0 END) OVER (PARTITION BY ID_NO, ENTRY_DATE) < 3
             THEN 'ALLOW' ELSE 'DENY'
        END) as NEW_COL
FROM NEW_TEST A;

答案 1 :(得分:1)

您需要创建一个合适的 JOIN。这是没有相关子查询的相同逻辑:

SELECT A.ID_NO,A.ENTRY_DATE,A.CATEGORY,
 NVL(B.NEW_COL, 'DENY') AS NEW_COL
  FROM NEW_TEST A
  LEFT JOIN (SELECT ID_NO, ENTRY_DATE, 'ALLOW' AS NEW_COL 
             FROM NEW_TEST B 
             WHERE CATEGORY IN ('ODS','L')
             GROUP BY B.ID_NO,B.ENTRY_DATE,B.CATEGORY
             HAVING COUNT(1)<3) B
  ON B.ID_NO=A.ID_NO AND B.ENTRY_DATE=A.ENTRY_DATE ;

您不需要窗口函数。您在 3 列上分组但在 2 列上加入似乎很奇怪,但我假设您知道这需要做什么。