Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 条纹的增量列_Sql_Sql Server_Tsql_Sql Server 2016_Gaps And Islands - Fatal编程技术网

Sql 条纹的增量列

Sql 条纹的增量列,sql,sql-server,tsql,sql-server-2016,gaps-and-islands,Sql,Sql Server,Tsql,Sql Server 2016,Gaps And Islands,如何获得以下以黄色突出显示的结果? 基本上,我想要一个计算字段,当VeganOption=1时,该字段递增1,当VeganOption=0时,该字段为零 我尝试过使用下面的查询,但是使用分区在0之后继续递增。我在这件事上有点纠结 SELECT [UniqueId] ,[Meal] ,[VDate] ,[VeganOption] , row_number() over (partition by [VeganOption] order by [Un

如何获得以下以黄色突出显示的结果?

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

我尝试过使用下面的查询,但是使用分区在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+

的,这是关于间隙和孤岛的变体

我喜欢用行号的差来定义条纹。这看起来像

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来枚举膳食


这里有一种方法。

一种方法是使用CTE定义分组,然后对这些分组进行进一步的行编号,从而产生:

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;

您可以使用SUM和ROW_编号创建子组:


它产生不正确的结果:。最后两行是4,5,而不是1,2@LukaszSzozda . . . 谢谢你把这些放在一起。我没有注意到日期不是唯一的。uniqueid是用于逻辑的正确列。我喜欢这种方法,它比其他传统的缺口和孤岛方法更容易理解。你应该将VeganOption设为0=0。第5,6行应为0,0,而不是1,2。第10行也是如此。我知道上面的投票显示了这一点,但看到一个精心设计的问题,有样本数据、预期结果、尝试,然后再加上CREATE和INSERT语句,真是太好了。谢谢@Larnu,而不是一个chagne从varchar到datetime的普通转换失败:-真正困扰我@ZoharPeled的是如何拆分这个分隔列表问题。这么多人。。。。英雄联盟
WITH cte AS (
  SELECT [UniqueId]
      ,[Meal]
      ,[VDate]
      ,[VeganOption]
      ,sum(CASE WHEN VeganOption = 1 THEN 0 ELSE 1 END) 
         over (order by [UniqueId]) AS grp  --switching 0 <-> 1
  FROM [Control]
)
SELECT *,CASE WHEN VeganOption =0 THEN 0
        ELSE ROW_NUMBER() OVER(PARTITION BY veganOption, grp ORDER BY [UniqueId])
        END AS VeganStreak                  -- main group and calculated subgroup
FROM cte
order by [UniqueId];