如何嵌套CTE(公用表表达式)

时间:2017-11-02 14:32:03

标签: sql oracle

我有以下查询

With max_cm1 as (select * from tableA)
Select * ,
 CASE WHEN TO_CHAR(CCP2.END_DATE,'MM/DD/YYYY') <> '09/09/9000' THEN 'CLOSED'
  WHEN MAX_CM1.MAX_ROLE_CM IS NOT NULL AND HIST.PCMUID IS NOT NULL     THEN 'ASSIGNED'
ELSE 'UNASSIGNED'
END STATUS
from max_cm1

现在我需要过滤case语句。我怎么能这样做?

2 个答案:

答案 0 :(得分:0)

您可以使用别名,例如:m

With max_cm1 as (select * from tableA)
Select m.* ,
 CASE WHEN TO_CHAR(CCP2.END_DATE,'MM/DD/YYYY') <> '09/09/9000' THEN 'CLOSED'
  WHEN MAX_CM1.MAX_ROLE_CM IS NOT NULL AND HIST.PCMUID IS NOT NULL     THEN 'ASSIGNED'
ELSE 'UNASSIGNED'
END STATUS
from max_cm1 m;

在您的情况下,您不需要CTE,除非您将其与其他表格一起加入CTE中的某些表达式。如果您只对A感兴趣,可以使用相同的方法直接从表select '*'中获取。

答案 1 :(得分:0)

你的问题不清楚。此外,给定的查询有点令人困惑,因为它使某些列具有不会出现在查询中其他位置的表名(CCP2和HIST)。此外,正如所写的那样,CTE似乎没有任何目的。

我假设你想要的是在结果集中包含给定的CASE表达式,但也在WHERE子句中使用它来过滤结果(例如WHERE CASE ... END = 'CLOSED'。简单的方法这是重复CASE表达式;但是当然复制逻辑永远不是一个好的选择。所以我认为更好的方法就是在CTE中包含派生列,这样你就可以引用它了。在WHERE子句中按名称。

看起来您可能也遇到了尝试选择所有列(*)和派生列的问题。解决这个问题的方法是使用表名或者其他答案中指示的别名来限定*。

把这一切放在一起,我相信你想要的东西如下。我保留了列表达式(例如HIST.PCMUID),因为你写的它们没有任何意义。我猜测tableA确实代表了多个表的连接。

WITH max_cm1 AS (
  SELECT tableA.* ,
   CASE WHEN TO_CHAR(CCP2.END_DATE,'MM/DD/YYYY') <> '09/09/9000' THEN 'CLOSED'
    WHEN MAX_CM1.MAX_ROLE_CM IS NOT NULL AND HIST.PCMUID IS NOT NULL     THEN 
    'ASSIGNED'
    ELSE 'UNASSIGNED'
    END STATUS
  FROM tableA
)
SELECT *
FROM max_cm1
WHERE status = 'CLOSED'