【问题标题】:SQL Case Statement (Understanding)SQL 案例语句(理解)
【发布时间】:2015-04-30 03:49:20
【问题描述】:

我在我的数据库中遇到了这个 case 语句。我试图弄清楚它的作用。基本上这个案例陈述试图做的是预测本周玩具的总和。以下是案例陈述,有人可以分解并向我解释一下。

case 
    when ROW_NUMBER() over(order by datetbl.[date]) <> COUNT(*) over() 
    then null 
    else isnull(case 
        when case 
            when ROW_NUMBER() over(order by datetbl.[date]) = COUNT(*) over() 
            then (sum([Toy])/(datepart(dw,getdate())-1))*7 
        end = 0 
        then sum(Toy) + 1 
        else case 
            when ROW_NUMBER() over(order by datetbl.[date]) = COUNT(*) over() 
            then (sum([Toy])/(datepart(dw,getdate())-1))*7 
        end 
    end,0) 
end [ToyForcast]

谢谢

【问题讨论】:

  • 哪个RDBMS(好像我不知道)
  • 哇...这是我最近看到的最疯狂的说法

标签: sql sql-server


【解决方案1】:

我已将 cmets 添加到查询中,以尝试逐点分解。

case 
    when ROW_NUMBER() over(order by datetbl.[date]) <> COUNT(*) over() --this checks if you are on the last row of your dataset, if you are not => put a null in this column
    then null 
    else isnull(case 
        when case 
            when ROW_NUMBER() over(order by datetbl.[date]) = COUNT(*) over() --on the last row
            then (sum([Toy])/(datepart(dw,getdate())-1))*7 --find the average of toys so far this week extrapolated out to the end of the week (presumably to figure out how many toys will be used(?) by the end of the week
        end = 0 --if there are going to be 0 toys used by the end of the week show sum(refire) + 1, whatever that signifies
        then sum(refire) + 1 
        else case 
            when ROW_NUMBER() over(order by datetbl.[date]) = COUNT(*) over() --again on the last row
            then (sum([Toy])/(datepart(dw,getdate())-1))*7 --show the extrapolated value using the average used per day so far
        end 
    end,0) --if after all of that we ended up with a null value for the extrapolated value, replace the null with 0
end [ToyForcast]

基本上,它会尝试仅对数据集的最后一行运行计算,因为我假设它是一个报告。然后它试图通过计算本周每天的平均玩具并将其乘以 7(以获得周末预测)来计算出周末的玩具价值是多少。如果该投影结果为 0,则将 refire + 1 的总和作为投影(不知道这可能意味着什么)。最后,如果我们因为没有数据而以 null 结束,则输入 0。

希望这会有所帮助,并且我的大脑没有错过任何东西。

【讨论】:

    【解决方案2】:

    显然我参加聚会有点太晚了,但我想建议一个(对我来说)更简单的方法来写这个。这应该返回相同的结果:

    case 
        when ROW_NUMBER() over(order by datetbl.[date]) <> COUNT(*) over() 
        then null 
        else 
           isnull(
              IIF(
                  ((sum([Toy])/(datepart(dw,getdate())-1))*7) = 0, 
                  sum(Toy) + 1, 
                  ((sum([Toy])/(datepart(dw,getdate())-1))*7)
              ),0) 
    end [ToyForcast]
    

    这是假设您至少使用 sql server 2012,因为它使用了IIF()。如果您使用 2008 r2 或更早的版本,您仍然可以跳过额外的内部 cases,因为我们已经很清楚我们在最后一行了。


    由于我已经准备了一些cmets,我也将它们发布:

    case when ROW_NUMBER() over(order by datetbl.[date]) <> COUNT(*) over() then null else
    

    基本上,ROW_NUMBER 将返回当前行号(按 日期 排序),如果这与总行数不同,它将返回 null。如果没有,它将继续:

    isnull(
     case when 
      case when ROW_NUMBER() over(order by datetbl.[date]) = COUNT(*) over() then 
    

    这(内壳)是我在顶部示例中删除的检查之一。这将检查当前行是否为最后一行,但我们已经从第一个 case 知道了这一点。

    (sum([Toy])/(datepart(dw,getdate())-1))*7 end = 0 then sum(Toy) + 1 else
       case when ROW_NUMBER() over(order by datetbl.[date]) = COUNT(*) over() then 
         (sum([Toy])/(datepart(dw,getdate())-1))*7 
       end 
    end,0)
    

    总和玩具的数量,然后除以从星期一过去的天数。然后将其乘以 7 以获得每周总数的近似值。如果这等于 0,则返回 玩具总和 + 1,否则返回第一个表达式(但首先检查不必要的“如果这是最后一行”)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-19
      • 2020-10-31
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-18
      相关资源
      最近更新 更多