条纹的增量列

时间:2018-08-21 17:54:19

标签: sql sql-server tsql sql-server-2016 gaps-and-islands

如何以黄色突出显示以下结果? enter image description here

基本上我想要一个计算字段,当VeganOption = 1时递增1,而当VeganOption = 0时递增零

我尝试使用以下查询,但使用分区后零继续增加。我对此有些卡住。

SELECT [UniqueId]
      ,[Meal]
      ,[VDate]
      ,[VeganOption]
      , row_number() over (partition by [VeganOption] order by [UniqueId])
  FROM [Control]
  order by [UniqueId]

表格数据:

CREATE TABLE Control
    ([UniqueId] int, [Meal] varchar(10), [VDate] datetime, [VeganOption] int);

INSERT INTO Control ([UniqueId], [Meal], [VDate], [VeganOption])
VALUES
('1', 'Breakfast',' 2018-08-01 00:00:00', 1),
('2', 'Lunch',' 2018-08-01 00:00:00', 1),
('3', 'Dinner',' 2018-08-01 00:00:00', 1),
('4', 'Breakfast',' 2018-08-02 00:00:00', 1),
('5', 'Lunch',' 2018-08-02 00:00:00', 0),
('6', 'Dinner',' 2018-08-02 00:00:00', 0),
('7', 'Breakfast',' 2018-08-03 00:00:00', 1),
('8', 'Lunch',' 2018-08-03 00:00:00', 1),
('9', 'Dinner',' 2018-08-03 00:00:00', 1),
('10', 'Breakfast',' 2018-08-04 00:00:00', 0),
('11', 'Lunch',' 2018-08-04 00:00:00', 1),
('12', 'Dinner',' 2018-08-04 00:00:00', 1)
;

这是用于SQL Server 2016 +

3 个答案:

答案 0 :(得分:6)

您可以使用void foo(auto&& x)然后使用void f(Sortable auto& x); 创建子组:

SUM

Rextester Demo

答案 1 :(得分:3)

这是空白和岛屿上的变种。

我喜欢使用行号的不同来定义条纹。看起来像

select c.*,
       (case when veganoption = 1
             then row_number() over (partition by veganoption, seqnum - seqnum_v order by uniqueid)
             else 0
        end) as veganstreak
from (select c.*,
             row_number() over (partition by veganoption order by uniqueid) as seqnum_v,
             row_number() over (order by uniqueid) as seqnum
      from c
     ) c;

为什么这个工作有点难以解释。但是,如果您查看子查询的结果,则会看到行号的差异如何定义要识别的条纹。其余的只是使用row_number()来枚举餐点。

这里是Rextester

答案 2 :(得分:3)

一种方法是使用CTE定义您的分组,然后对它们进行进一步的ROW_NUMBER(),从而产生:

WITH Grps AS(
    SELECT *,
           ROW_NUMBER() OVER (ORDER BY UniqueID ASC) - 
           ROW_NUMBER() OVER (PARTITION BY VeganOption ORDER BY UniqueID ASC) AS Grp
    FROM Control)
SELECT *,
       CASE VeganOption WHEN 0 THEN 0 ELSE ROW_NUMBER() OVER (PARTITION BY Grp ORDER BY UniqueID ASC) END
FROM Grps
ORDER BY UniqueId;