案例陈述覆盖其他案例

时间:2018-02-23 13:32:05

标签: sql sql-server case

在下面的case语句中,值'1'被分配给那些开始时间为2019年9月的人,而值'3'应该被分配。

此外,尽管在查询中被排除在外,但那些L._Stage为“不感兴趣”的人仍被包含在搜索中。

SELECT
U.*,
L.ID AS Lead_ID,

CASE

WHEN (L.Age_Change > 180) OR (L.Age_Change IS NULL AND L._Stage IS NOT NULL) AND
(L._Stage NOT LIKE '%Not Interested%' AND
 L._Stage NOT LIKE '%Duplicate%') AND
(L.Start_Term NOT LIKE '%September 2019%' AND  
 L.Start_Term NOT LIKE '%September 2020%' AND 
 L.Start_Term NOT LIKE '%September 2021%') THEN '1' 

WHEN (L._Stage IS NULL AND L.Created_Date < DATEADD(day,-45, GETDATE()) AND 
(L.Start_Term NOT LIKE '%September 2019%' AND 
 L.Start_Term NOT LIKE '%September 2020%' AND 
 L.Start_Term NOT LIKE '%September 2021%') THEN '2'

WHEN (L.Age_Change > 180) OR (L.Age_Change IS NULL AND L._Stage IS NOT NULL) AND
(L._Stage NOT LIKE '%Not Interested%' AND
 L._Stage NOT LIKE '%Duplicate%') AND
(L.Start_Term LIKE '%September 2019%' AND 
 L.Start_Term LIKE '%September 2020%' AND 
 L.Start_Term LIKE '%September 2021%') THEN '3'

 ELSE NULL END AS Case_Logic

修改

我已将字段L.Age_Change更新为接受INT的字段,此更改将反映在上面的查询中。

示例数据:

Lead ID  L.Age_Change L._Stage    L.Start_Term     Expected Case Logic
0001     200          Interested  September 2018   '1'
0002     NULL         Interested  September 2018   '1'
0003     NULL         Interested  September 2019   '3'
0004     182          Interested  September 2019   '3'
0005     250          Interested  September 2020   '3'

在上述情况中,'0003','0004'和'0005'都被指定为案例逻辑值'1'而不是'3'。

非常感谢有关该问题的任何指导

4 个答案:

答案 0 :(得分:1)

除了CASE之外,您的Start_Term语句也有所不同。在CASE 3您正在使用L.Age_Last__Stage_Change < DATEADD(day,-180, GETDATE()),而CASE 1正在使用(L.Age_Change < DATEADD(day,-180, GETDATE()))

因此,将其更改为以下语句,如果返回正确的结果,那么您就知道了,因为您正在混淆L.Age_ChangeL.Age_Last__Stage_Change,您需要更改逻辑。

WHEN (L.Age_Change < DATEADD(day,-180, GETDATE())) OR (L.Age_Change IS NULL 
AND L._Stage IS NOT NULL) AND
(L._Stage NOT LIKE '%Not Interested%' AND
 L._Stage NOT LIKE '%Duplicate%') AND
(L.Start_Term NOT LIKE '%September 2019%' AND  
 L.Start_Term NOT LIKE '%September 2020%' AND 
 L.Start_Term NOT LIKE '%September 2021%') THEN '1' 

WHEN (L._Stage IS NULL AND L.Created_Date < DATEADD(day,-45, GETDATE()) AND 
(L.Start_Term NOT LIKE '%September 2019%' AND 
 L.Start_Term NOT LIKE '%September 2020%' AND 
 L.Start_Term NOT LIKE '%September 2021%') THEN '2'

WHEN (L.Age_Last__Stage_Change < DATEADD(day,-180, GETDATE())) OR 
(L.Age_Last__Stage_Change IS NULL AND L._Stage IS NOT NULL) AND
(L._Stage NOT LIKE '%Not Interested%' AND
 L._Stage NOT LIKE '%Duplicate%') AND
(L.Start_Term LIKE '%September 2019%' AND 
 L.Start_Term LIKE '%September 2020%' AND 
 L.Start_Term LIKE '%September 2021%') THEN '3'

答案 1 :(得分:0)

尝试以下方法。如果你缩进所有内容,那么更容易看出错误在哪里:

CASE
    WHEN (
                L.Age_Change < DATEADD(day,-180, GETDATE()) 
            OR  (L.Age_Change IS NULL AND L._Stage IS NOT NULL)
         ) 
        AND (
                    L._Stage NOT LIKE '%Not Interested%' 
                AND L._Stage NOT LIKE '%Duplicate%' 
                AND L.Start_Term NOT LIKE '%September 2019%'
                AND L.Start_Term NOT LIKE '%September 2020%' 
                AND L.Start_Term NOT LIKE '%September 2021%'
            ) THEN '1' 

    WHEN        L._Stage IS NULL AND L.Created_Date < DATEADD(day,-45, GETDATE()) 
            AND L.Start_Term NOT LIKE '%September 2019%' 
            AND L.Start_Term NOT LIKE '%September 2020%' 
            AND L.Start_Term NOT LIKE '%September 2021%' THEN '2'

    WHEN (
                L.Age_Change < DATEADD(day,-180, GETDATE()) 
            OR (L.Age_Change IS NULL AND L._Stage IS NOT NULL)
         ) 
        AND (
                    L._Stage NOT LIKE '%Not Interested%' 
                AND L._Stage NOT LIKE '%Duplicate%') 
                AND (
                            L.Start_Term LIKE '%September 2019%' 
                        OR  L.Start_Term LIKE '%September 2020%' --Changed AND to OR, because an value cannot be LIKE '%September 2019%' AND LIKE '%September 2020%', it's one or the other (I assume)
                        OR  L.Start_Term LIKE '%September 2021%'
                    )
            ) THEN '3'

 ELSE NULL 
 END

答案 2 :(得分:0)

你混合ORAND条件而不使用它们之间的括号,这绝不是一个好主意。 AND将优先,您的查询在写得更具可读性时,将如下所示:

WHEN 
L.Age_Change < DATEADD(day,-180, GETDATE())    
OR 
(
  L.Age_Change IS NULL 
  AND L._Stage IS NOT NULL 
  AND L._Stage NOT LIKE '%Not Interested%' 
  AND L._Stage NOT LIKE '%Duplicate%' 
  AND L.Start_Term NOT LIKE '%September 2019%' 
  AND L.Start_Term NOT LIKE '%September 2020%' 
  AND L.Start_Term NOT LIKE '%September 2021%'
) 
THEN '1' 

如果第一部分为真,或者其他一切都为真,则评估为TRUE

您可能希望将OR条件置于括号内,例如:

WHEN 
(
   L.Age_Change < DATEADD(day,-180, GETDATE()) 
   OR 
   L.Age_Change IS NULL
)
AND L._Stage IS NOT NULL 
AND L._Stage NOT LIKE '%Not Interested%' 
AND L._Stage NOT LIKE '%Duplicate%' 
AND L.Start_Term NOT LIKE '%September 2019%' 
AND L.Start_Term NOT LIKE '%September 2020%' 
AND L.Start_Term NOT LIKE '%September 2021%'
THEN '1' 

和第三种情况相同

另请注意,在行的开头使用AND/OR并为每个括号添加适当的缩进可以帮助您避免犯错。

答案 3 :(得分:0)

由于案例1和案例3有相似之处,如果我们将它们组合成一个嵌套案例,则可能是更好的方法。

<强>已更新

SELECT
L.Lead_ID,
L.Age_Change, 
L._Stage, 
L.Start_Term,
CASE
    WHEN 
        (L.Age_Change > 180 OR L.Age_Change IS NULL )
    AND L._Stage IS NOT NULL
    AND L._Stage NOT IN('Not Interested', 'Duplicate')
    THEN 
        CASE
            WHEN  L.Start_Term NOT IN('September 2019', 'September 2020', 'September 2021') THEN 1
            WHEN  L.Start_Term IN('September 2019', 'September 2020', 'September 2021') THEN 3
        END
    WHEN 
        L.Age_Change BETWEEN 45 AND 180
    AND L._Stage IS NULL
    AND L.Start_Term IN('September 2019', 'September 2020', 'September 2021')   
    THEN 2
    ELSE NULL 
END AS Case_Logic
FROM test L

结果:

| Lead_ID | Age_Change |         _Stage |     Start_Term | Case_Logic |
|---------|------------|----------------|----------------|------------|
|       1 |        200 |     Interested | September 2018 |          1 |
|       2 |     (null) |     Interested | September 2018 |          1 |
|       3 |     (null) |     Interested | September 2019 |          3 |
|       4 |        182 |     Interested | September 2019 |          3 |
|       5 |        250 |     Interested | September 2020 |          3 |

这样可以避免使用OR并使查询保持简短而不是在同一列上重复条件(即使它有差异)。

如果我们知道架构并有适当的样本进行测试,我们甚至可以缩短它。

更新:

由于您清除了_StageStart_Term都是VARCHAR,并且它们不是任何其他字符串的一部分。 您可以使用上述解决方案,因为如果短语是另一个字符串的一部分(如句子​​),或者您不知道完全匹配,LIKE会更好。但是IN会做同样的事情,如果它是完全匹配的话,那就是它。

您仍然可以使用LIKEIN中的任何一个,这只取决于您的数据以及哪种方式可以更好地使用它。

注意由于您没有提供足够的样本来覆盖第三种情况(案例#2),我尝试复制案例,并将查询中的条件添加到提供的内容中,一切都可以正常使用示例逻辑。

演示:SQLFiddle