SQL:达到SUM阈值后显示记录

时间:2018-07-31 21:03:54

标签: sql sql-server

我有一张表格,按日期值(ASC)排序。

+----+------------+-------+
| Id |    Date    | Value |
+----+------------+-------+
|  1 | 2018-01-01 |    10 |
|  2 | 2018-01-02 |     5 |
|  3 | 2018-01-03 |    15 |
|  4 | 2018-01-04 |     0 |
|  5 | 2018-01-05 |     5 |
|  6 | 2018-01-06 |    10 |
|  7 | 2018-01-07 |     5 |
|  8 | 2018-01-08 |     0 |
|  9 | 2018-01-09 |     0 |
| 10 | 2018-01-10 |    10 |
+----+------------+-------+

我想创建一个视图,该视图仅在Value的SUM大于30时才从第一条记录开始返回记录。 因此,我的阈值为30,应该隐藏每个值都适合前30的记录。 一旦达到此阈值,则需要显示所有记录。

这意味着我所需的结果如下:

+----+------------+-------+
| Id |    Date    | Value |
+----+------------+-------+
|  4 | 2018-01-04 |     0 |
|  5 | 2018-01-05 |     5 |
|  6 | 2018-01-06 |    10 |
|  7 | 2018-01-07 |     5 |
|  8 | 2018-01-08 |     0 |
|  9 | 2018-01-09 |     0 |
| 10 | 2018-01-10 |    10 |
+----+------------+-------+

如您所见,Id的1、2和3被忽略了,因为它们的值(10、5和15)总和为30。 一旦达到此阈值,其余的记录就可见(甚至是ID 4的0值)。

我创建了一些脚本来设置带有数据的测试表:

-- Create test table
CREATE TABLE thresholdTest (
    [Id] INT IDENTITY(1,1) PRIMARY KEY,
    [Date] DATE NOT NULL,
    [Value] INT NOT NULL
)

-- Insert dummies
INSERT INTO [thresholdTest] ([Date],[Value])
VALUES
('2018-01-01',10),
('2018-01-02',5),
('2018-01-03',15),
('2018-01-04',0),
('2018-01-05',5),
('2018-01-06',10),
('2018-01-07',5),
('2018-01-08',0),
('2018-01-09',0),
('2018-01-10',10);

-- Select ordered by date
SELECT *
FROM [thresholdTest]
ORDER BY [Date] ASC

我所需要的只是一个SELECT语句/视图。 阈值始终是静态的(在此示例中为30)。 数据当然可以有所不同,但始终按日期排序并包含值。

谢谢。

3 个答案:

答案 0 :(得分:2)

您可以尝试在子查询中将SUM window函数一起使用以累积totle,然后在主查询中写入条件。

select Id,
      Date,
      Value
from 
(
  SELECT *,
         SUM(Value) OVER(ORDER BY Date) totle
  FROM thresholdTest
) t
WHERE totle > 30 OR (Value = 0 AND totle = 30)

[结果]

| Id |       Date | Value |
|----|------------|-------|
|  4 | 2018-01-04 |     0 |
|  5 | 2018-01-05 |     5 |
|  6 | 2018-01-06 |    10 |
|  7 | 2018-01-07 |     5 |
|  8 | 2018-01-08 |     0 |
|  9 | 2018-01-09 |     0 |
| 10 | 2018-01-10 |    10 |

sqlfiddle

答案 1 :(得分:2)

我将使用窗口功能:

;with cte as(
select *,  tot = sum([Value]) over (order by [Date])
from thresholdTest
)

select 
   Id, 
   [Date], 
   [Value]
from cte
where 
    (tot >= 30 and [Value] = 0)
    or tot > 30

答案 2 :(得分:1)

还有另一种方法

select t1.id, t1.Date,t1.Value
from [thresholdTest] t1
inner join [thresholdTest] t2 on t1.id >= t2.id
group by t1.id, t1.value, t1.Date
HAVING SUM(t2.VAlue)>30 OR( SUM(t2.value)=30 AND t1.value=0)