【问题标题】:SSMS (SQL) Not recognizing CASE WHEN... jumps to last ELSE 0SSMS (SQL) 无法识别 CASE WHEN... 跳转到最后一个 ELSE 0
【发布时间】:2018-08-09 23:19:15
【问题描述】:

例如,这会返回 55 的 ORDER NUMBER 和 55 的 Calc_ORDER_NUMBER_LAG,Calc_Qty_Changed 列不会给我 2,即使它们相等...

USE MfgMetrics

SELECT 
    [ORDER NUMBER], 
    [Calc_ORDER_NUMBER_LAG] = LAG([ORDER NUMBER],1,0) 
                                 OVER (Order By [ORDER NUMBER],[FileDate]), 
                                 --Order Number and File Date 
    [Order_Quantity], 
    [Calc_Order_Quantity_LAG] = LAG([Order_Quantity],1,0) 
                                   OVER (Order By [ORDER NUMBER], [FileDate]),
    [Calc_Qty_Changed] = 
        (CASE 
            WHEN [ORDER NUMBER] = [Calc_ORDER_NUMBER_LAG] THEN 2
            WHEN [ORDER NUMBER] != [Calc_ORDER_NUMBER_LAG] AND 
                        [Order_Quantity] != [Calc_Order_Quantity_LAG] AND 
                        [ACTUAL START DATE] != 0 AND 
                        [FileDate] >= [ACTUAL START DATE] THEN 1
            ELSE 0
        END)
FROM 
    dbo.Table_II

为什么每次都跳到ELSE 0,即使满足其他CASE WHEN条件?

【问题讨论】:

  • 需要查看您的数据和结果。
  • 单独查询是没有用的。给出示例输入和输出。
  • 我很难相信所写的查询实际上会运行。当它在计算中遇到列别名时,它应该抛出一个 Invalid Column Name 错误。顺便说一句,这就是建议的答案有效的原因。

标签: sql-server case-when dbo


【解决方案1】:

您应该在 CASE 语句中重新编写 LAG() 函数。

create table table_II([ORDER NUMBER] int, [Order_Quantity] int, [FileDate] date);
insert into table_II values
(1, 10, '20180101'),
(2, 20, '20180102'),
(2, 30, '20180103');
GO
3 行受影响
SELECT 
    [ORDER NUMBER], 
    [Calc_ORDER_NUMBER_LAG] = LAG([ORDER NUMBER]) OVER (Order By [ORDER NUMBER], [FileDate]), 
    [Order_Quantity], 
    [Calc_Order_Quantity_LAG] = LAG([Order_Quantity]) OVER (Order By [ORDER NUMBER], [FileDate]),
    [Calc_Qty_Changed] = 
        (CASE 
            WHEN [ORDER NUMBER] = LAG([ORDER NUMBER]) OVER (Order By [ORDER NUMBER], [FileDate]) 
                 THEN 2
            WHEN [ORDER NUMBER] != LAG([ORDER NUMBER]) OVER (Order By [ORDER NUMBER], [FileDate]) 
                 AND [Order_Quantity] != LAG([Order_Quantity]) OVER (Order By [ORDER NUMBER], [FileDate]) 
                 --AND [ACTUAL START DATE] != 0 
                 --AND [FileDate] >= [ACTUAL START DATE] 
                 THEN 1
            ELSE 0
        END)
FROM 
    dbo.Table_II
GO
订单号 | Calc_ORDER_NUMBER_LAG |订单_数量 | Calc_Order_Quantity_LAG | Calc_Qty_Changed ------------: | --------------------: | -------------: | ----------------------: | ---------------: 1 | | 10 | | 0 2 | 1 | 20 | 10 | 1 2 | 2 | 30 | 20 | 2

dbfiddle here

【讨论】:

  • 嗨 McNets!看起来您的解决方案与上面的解决方案非常相似,它有效。感谢您抽出宝贵时间提供帮助。我之前也从未见过 dbfiddle,这太棒了!再次感谢您!
【解决方案2】:

我猜,因为我不知道数据长什么样,你应该这样做:

USE MfgMetrics 
SELECT [ORDER NUMBER],
[Calc_ORDER_NUMBER_LAG] = LAG([ORDER NUMBER],1,0) OVER (Order By [ORDER NUMBER],[FileDate]), --Order Number and File Date
[Order_Quantity],
[Calc_Order_Quantity_LAG] = LAG([Order_Quantity],1,0) OVER (Order By [ORDER NUMBER], [FileDate]),
[Calc_Qty_Changed] = (CASE 
    WHEN [ORDER NUMBER]=LAG([ORDER NUMBER],1,0) OVER (Order By [ORDER NUMBER],[FileDate]) THEN 2 
    WHEN [ORDER NUMBER]!=LAG([ORDER NUMBER],1,0) OVER (Order By [ORDER NUMBER],[FileDate]) 
        AND [Order_Quantity] != LAG([Order_Quantity],1,0) OVER (Order By [ORDER NUMBER], [FileDate]) AND [ACTUAL START DATE] != 0 AND [FileDate] >= [ACTUAL START DATE] 
    THEN 1 
    ELSE 0 END) 
FROM dbo.Table_II

【讨论】:

  • 您好 user3532232!太感谢了!这就像一个魅力。你能帮忙解释一下在 CASE WHEN 的每个部分中添加 OVER(Order by ...)的效果吗?我对 SQL 还很陌生,想更好地了解人们何时花时间伸出援助之手!再次感谢您!
  • 您计算第二列中的 [calc_ORDER_NUMBER_LAG] 然后尝试在最后一列中使用该值。这个不行,需要在最后一列重新计算。或者,您可以使用计算值进行外部查询。
猜你喜欢
  • 2017-08-19
  • 1970-01-01
  • 2015-11-02
  • 1970-01-01
  • 2022-10-19
  • 1970-01-01
  • 1970-01-01
  • 2017-09-11
  • 2017-03-15
相关资源
最近更新 更多