每个月检查一次价值

时间:2016-01-04 10:11:19

标签: sql entity-framework linq tsql

我有这张桌子

declare @tbl table(dDay datetime, data int)
insert into @tbl values ('2014-11-14 11:03:18',20)
insert into @tbl values ('2014-12-17 09:22:03',50)
insert into @tbl values ('2014-11-14 10:38:06',35)
insert into @tbl values ('2014-12-14 10:41:24',10)
insert into @tbl values ('2014-11-14 10:44:53',13)
insert into @tbl values ('2014-11-17 09:22:03',11)
insert into @tbl values ('2013-03-22 17:46:02',111)

+----------------------------+------+
|            dDay            | data |
+----------------------------+------+
| March, 22 2013 17:46:02    |  111 |
| November, 14 2014 10:38:06 |   35 |
| November, 14 2014 10:44:53 |   13 |
| November, 14 2014 11:03:18 |   20 |
| November, 17 2014 09:22:03 |   11 |
| December, 14 2014 10:41:24 |   10 |
| December, 17 2014 09:22:03 |   50 |
+----------------------------+------+

如果数据大于X,我如何每月检查一次?

例如,我想对这些值求和,但如果在任何月份它的值大于50,则必须从头开始求和。

此处11月的数据为(20 + 35 + 13 + 11)及其7979 > 50。所以在12月肯定不会有(20 + 35 + 13 + 11) + 50 + 10。相反,必须有50 + 10(在这种情况下为60)。而且对于所有月份

寻找输出:

+-------+-------------------+
| month |        sum        |
+-------+-------------------+
|     3 | 111               |
|    11 | 20 + 35 + 13 + 11 |
|    12 | 50 + 10           |
+-------+-------------------+

2 个答案:

答案 0 :(得分:1)

<强>计划

  
      
  • 按月分组的数据总和为sum_data_v
  •   
  • row_number带到sum_data_v
  •   
  • 在连续的row_numbers
  • 上面加入自身   
  • 通过对重置指示符求和来计算分区逻辑,如果前一个月sum_data> 50
  •   
  • 将sum_data与上面计算的分区相加
  •   

<强>设置

create view sum_data_v
as
select month(dDay) as mnth, sum(data) as sum_data
from [table]
group by month(dDay)
;

示例输入

+----------------------------+------+
|            dDay            | data |
+----------------------------+------+
| March, 22 2013 17:46:02    |  111 |
| May, 22 2013 17:46:02      |   22 |
| June, 22 2013 17:46:02     |   13 |
| July, 22 2013 17:46:02     |   17 |
| November, 14 2014 10:38:06 |   35 |
| November, 14 2014 10:44:53 |   13 |
| November, 14 2014 11:03:18 |   20 |
| November, 17 2014 09:22:03 |   11 |
| December, 14 2014 10:41:24 |   10 |
| December, 17 2014 09:22:03 |   50 |
+----------------------------+------+

<强>查询

select [month],
SUM(sum_data) OVER(partition by 
                   prt
                   ORDER BY [month] 
                   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS csum
from
(
select 
[left].mnth as [month],
[left].sum_data,
sum(case when ([right].mnth is not null and [right].sum_data > 50)
         then 1
         else 0
         end) 
over(order by [left].mnth
     ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as prt
from
(
select mnth, sum_data,
row_number() over(order by mnth) as rn
from sum_data_v
) [left]
left join
(
select mnth, sum_data,
row_number() over(order by mnth) as rn
from sum_data_v
) [right]
on [left].rn = [right].rn + 1
) [parts]
order by [month]
;

<强>输出

+-------+------+
| month | csum |
+-------+------+
|     3 |  111 |
|     5 |   22 |
|     6 |   35 |
|     7 |   52 |
|    11 |  131 |
|    12 |   60 |
+-------+------+

<强> sqlfiddle

答案 1 :(得分:0)

请试试这个。

filename.xlsx P10