带有 CASE 的 WHERE 条件

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

参考粗体部分,基本上有产品代码,并在案例说明中添加产品的合格年龄。所以下面我们有年龄为 18 岁或 14 岁的产品来使用产品。创建了一个新列作为“资格”

现在提到第二个粗体部分,我只想要“资格”>“AgeAtOpenDate”的账户,即账户持有人对于账户来说太年轻了。

SELECT 
    CASE
        WHEN EOMONTH(OpenDate,0) = a.[EtlFileDate] THEN 'New Account'
        ELSE 'Existing Account'
        END AS 'NewAccountsInMonth'
    ,CASE
        **WHEN a.[ProductCode] in (801,802) THEN '18'
        WHEN a.[ProductCode] in (480,481,489,490) THEN '14'
        END as 'Eligibility'**
    ,a.[EtlFileDate]
    ,a.[AccountNumber]
    ,a.[OpenDate] 
    ,a.[ProductCode]
    ,a.[ProductName]  
    ,a.[PrimaryCAN]
    ,b.[Cust_Age]
    ,b.[Cust_BirthDate]
    ,**(DATEDIFF(year,b.[Cust_BirthDate],a.[OpenDate] ) as 'AgeAtOpenDate'**
FROM Histaccounts a
join Marketable b
    on a.[PrimaryCAN]=b.[CAN]
**where 'Eligibility'>'AgeAtOpenDate'**
    and a.[EtlFileDate] between '2021-10-31' and '2023-03-23' 
    and a.[ProductCode] in (480,481,489,490,802,801)

当我运行上面的脚本时,我仍然得到所有结果,而不是未满年龄的结果。

我做错了什么?这是否与您不能在 SELECT 区域中使用基于 CASE 的 WHERE 条件有关?

sql sql-server case
4个回答
0
投票

问题是您不能在 SELECT 语句中定义的 WHERE 子句中使用别名。 WHERE 子句在 SELECT 语句之前求值,因此别名

Eligibility
AgeAtOpenDate
WHERE 子句中不被识别。

您可以这样重写您的查询:

SELECT *
FROM (
    SELECT 
        CASE
            WHEN EOMONTH(OpenDate,0) = a.[EtlFileDate] THEN 'New Account'
            ELSE 'Existing Account'
        END AS 'NewAccountsInMonth',
        CASE
            WHEN a.[ProductCode] in (801,802) THEN '18'
            WHEN a.[ProductCode] in (480,481,489,490) THEN '14'
        END as 'Eligibility',
        a.[EtlFileDate],
        a.[AccountNumber],
        a.[OpenDate],
        a.[ProductCode],
        a.[ProductName],
        a.[PrimaryCAN],
        b.[Cust_Age],
        b.[Cust_BirthDate],
        DATEDIFF(year,b.[Cust_BirthDate],a.[OpenDate] ) as 'AgeAtOpenDate'
    FROM Histaccounts a
    JOIN Marketable b
    ON a.[PrimaryCAN]=b.[CAN]
    WHERE a.[EtlFileDate] BETWEEN '2021-10-31' AND '2023-03-23' 
        AND a.[ProductCode] IN (480,481,489,490,802,801)
) subquery
WHERE subquery.Eligibility > subquery.AgeAtOpenDate

0
投票

这里有几个问题,但最大的是

'Eligibility'
子句中的值
'AgeAtOpenDate'
WHERE
被解释为字符串文字,而不是对列别名的引用,并且由于
E
大于
A 
条件总是成功。

您可以通过多种方式解决此问题,但在这种情况下,您最好不要重复

CASE
表达式。做exactly,SQL Server足够聪明,知道
SELECT
WHERE
子句中的表达式是相同的,只会计算一次。任何类型的嵌套或分层,您都有可能失去对可能有助于查询的索引的使用。


0
投票

你能尝试用整个逻辑替换 in where 子句吗

where (CASE WHEN a.[ProductCode] in (801,802) THEN '18'
WHEN a.[ProductCode] in (480,481,489,490) THEN '14'
END > (DATEDIFF(year,b.[Cust_BirthDate],a.[OpenDate] > (DATEDIFF(year,b.[Cust_BirthDate],a.[OpenDate] )) > (DATEDIFF(year,b.[Cust_BirthDate],a.[OpenDate] )) and a.[EtlFileDate] between '2021-10-31' and '2023-03-23' and a.[ProductCode] in (480,481,489,490,802,801)

-1
投票

您可以在临时表中插入记录,然后应用过滤器

SELECT 
CASE
WHEN EOMONTH(OpenDate,0) = a.[EtlFileDate] THEN 'New Account'
ELSE 'Existing Account'
END AS 'NewAccountsInMonth'
,CASE WHEN a.[ProductCode] in (801,802) THEN '18'
WHEN a.[ProductCode] in (480,481,489,490) THEN '14'
END as 'Eligibility'
,a.[EtlFileDate]
,a.[AccountNumber]
,a.[OpenDate] 
,a.[ProductCode]
,a.[ProductName]  
,a.[PrimaryCAN]
,b.[Cust_Age]
,b.[Cust_BirthDate]
,(DATEDIFF(year,b.[Cust_BirthDate],a.[OpenDate] ) as [AgeAtOpenDate]
into #Test
FROM Histaccounts a
join Marketable b
on a.[PrimaryCAN]=b.[CAN]
WHERE a.[EtlFileDate] between '2021-10-31' and '2023-03-23' and a.[ProductCode] in (480,481,489,490,802,801)

SELECT * from #Test
WHERE Eligibility>AgeAtOpenDate

CTE

WITH CTE AS
(
SELECT 
CASE
WHEN EOMONTH(OpenDate,0) = a.[EtlFileDate] THEN 'New Account'
ELSE 'Existing Account'
END AS 'NewAccountsInMonth'
,CASE WHEN a.[ProductCode] in (801,802) THEN '18'
WHEN a.[ProductCode] in (480,481,489,490) THEN '14'
END as 'Eligibility'
,a.[EtlFileDate]
,a.[AccountNumber]
,a.[OpenDate] 
,a.[ProductCode]
,a.[ProductName]  
,a.[PrimaryCAN]
,b.[Cust_Age]
,b.[Cust_BirthDate]
,(DATEDIFF(year,b.[Cust_BirthDate],a.[OpenDate] ) as [AgeAtOpenDate]
into #Test
FROM Histaccounts a
join Marketable b
on a.[PrimaryCAN]=b.[CAN]
WHERE a.[EtlFileDate] between '2021-10-31' and '2023-03-23' and a.[ProductCode] in (480,481,489,490,802,801)
)
SELECT * from CTE
WHERE Eligibility>AgeAtOpenDate
© www.soinside.com 2019 - 2024. All rights reserved.