在 WHERE 子句中重用计算的 CASE 列?

问题描述 投票:0回答:1

我有一个疑问:

SELECT id
    , CASE WHEN id LIKE 'A_SEQ%' THEN 'amber'
    WHEN TestReason = 'itf' THEN 'red'
    ELSE NULL END AS amberRed
FROM db.tbl1

我想将某些内容分类为

red
amber
并排除其他所有内容。

这背后的原因是因为如果我不排除

NULL
,生成的数据集深度为 144,000,000(1.44 亿)行;如果排除
NULL
,它就会减少到仅仅 878,000。

我继续阅读的一般建议是尝试这种方法,但它不起作用,因为

amberRed
列未被识别:

SELECT id
    , CASE WHEN id LIKE 'A_SEQ%' THEN 'amber'
    WHEN TestReason = 'itf' THEN 'red'
    ELSE NULL END AS amberRed
FROM db.tbl1
WHERE amberRed IS NOT NULL

我怎样才能实现这个目标?

sql sql-server tsql
1个回答
3
投票

在 SQL Server 中,您无法在

WHERE
子句中使用计算列,只能在
ORDER BY
子句中使用。

因此,您要么需要某种形式的子查询,要么必须重复计算。

CROSS APPLY
是实现这一目标的好方法。

SELECT T1.id, X.AmberRed
FROM db.tbl1 T1
CROSS APPLY (VALUES (
    CASE WHEN T1.id LIKE 'A_SEQ%' THEN 'amber'
    WHEN TestReason = 'itf' THEN 'red'
    ELSE NULL END
)) AS X (AmberRed)
WHERE X.AmberRed IS NOT NULL;

但是一个简单的子查询也可以完成这项工作

SELECT X.id, X.AmberRed
FROM (
    SELECT T1.id
        , CASE WHEN T1.id LIKE 'A_SEQ%' THEN 'amber'
        WHEN TestReason = 'itf' THEN 'red'
        ELSE NULL END
    FROM db.tbl1 T1
) X
WHERE X.AmberRed IS NOT NULL;

或者你甚至可以重复这个表达,如果它很简单:

SELECT T1.id
    , CASE WHEN T1.id LIKE 'A_SEQ%' THEN 'amber'
    WHEN TestReason = 'itf' THEN 'red'
    ELSE NULL END
FROM db.tbl1 T1
WHERE CASE WHEN T1.id LIKE 'A_SEQ%' THEN 'amber'
    WHEN TestReason = 'itf' THEN 'red'
    ELSE NULL END IS NOT NULL;
© www.soinside.com 2019 - 2024. All rights reserved.