【问题标题】:I need to merge date rows to a snapshot month row in SQL Server 2008 R2我需要将日期行合并到 SQL Server 2008 R2 中的快照月行
【发布时间】:2015-07-29 01:31:10
【问题描述】:

您好,感谢您的帮助!我正在使用 SQL Server 2008 R2

 Cust  Date  Opening   Count    Count    Count     Count    Closing
  1    01/1/x   1        0        0         0         0         1
  1    ....     1        0       -1         0         0         0
  1    31/1/x   0        0        0        +1         0         1

  2    05/1/x   0       +1        0         0         0         1
  2    ....     1        0       -1         0         0         0
  2    31/1/x   0        0        0        +1         0         1

上表是我正在处理的一个示例。此表显示每天的期初余额、变动和期末余额。昨天收盘就是今天开盘,中间的横线是动作,一切都是计数。

我需要按如下方式将其汇总到每月快照表中,

 Cust   Month  Opening   Count    Count    Count     Count    Closing
  1    1/x      1        0       -1        +1         0         1
  2    1/x      0       +1       -1        +1         0         1

我在一张大桌子上做这个,所以它需要有效率,基本上,我必须在一个月的第一天开门,如果客户是在这个月晚些时候(不是第一个)添加的,那么该月的开盘价为 0,否则我可以将前一天的收盘价作为今天的开盘价。计数列跟踪白天的运动,我知道一列总是有正数或负数 1。所以对于运动,我可以使用 MIN/MAX 和分组依据。

我很难找到一种干净有效的方法来基本上合并所有每日行,同时从一个月的第一天开始,从最后一个月开始关闭。

我尝试过按客户使用 ROW_NUMBER() 分区,按日期排序,然后将最低行作为开始,将最高行作为结束,但是当本月 1 日没有行时,这会出错。

有人能指出我正确的方向吗?

提前致谢。

【问题讨论】:

    标签: sql sql-server-2008-r2


    【解决方案1】:

    尝试在 SUM() 聚合函数中为 Open 和 close 值使用 CASE 语句。比如……

    SELECT ...
           SUM( CASE WHEN MONTH(DATEADD(DAY, -1, MyTable.Date)) != MONTH(MyTable.Date) THEN MyTable.Opening ELSE 0 END ) AS Opening,
           SUM( CASE WHEN MONTH(DATEADD(DAY, 1, MyTable.Date)) != MONTH(MyTable.Date) THEN MyTable.Closing ELSE 0 END ) AS Closing
    FROM MyTable
    ....
    

    【讨论】:

    • 不客气。乐意效劳。如果您愿意,请通过将其标记为您的答案来“结束”该问题。
    【解决方案2】:

    我认为您只需要条件聚合。我觉得你的逻辑有点难以理解。假设值不是负数,您可以使用以下方法获得开仓和收盘金额:

    select cust, year(date), month(date),
           max(case when day(date) = 1 then open else 0 end) as open,
           max(case when day(dateadd(day, 1 date)) = 1 then close else 0 end) as close
           . . .
    from table t
    group by cust, year(date), month(date);
    

    如果有必要,一个相对简单的修改可以处理负值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-20
      • 2013-03-19
      相关资源
      最近更新 更多