Sql 分组数据以创建范围列

Sql 分组数据以创建范围列,sql,sql-server,Sql,Sql Server,我有下表: Row Column Type 1 1 = 1 2 = 1 3 O 1 4 = 1 5 = 1 6 O 2 1 = 我需要得到这样的东西 Row Start_Column End_Column Type 1 1 2 = 1 3

我有下表:

Row   Column   Type
1     1        =
1     2        =
1     3        O
1     4        =
1     5        =
1     6        O
2     1        =
我需要得到这样的东西

Row   Start_Column   End_Column   Type
1     1              2           =
1     3              3           O
1     4              5           =
1     6              6           O
2     1              1           =
我试着对它进行分组,用行数、排名进行操作,但没有运气

有人知道怎么做吗?

您可以使用LAG和SUM窗口函数创建所需的组,然后进行聚合:

SELECT [Row], 
       MIN([Column]) Start_Column, 
       MAX([Column]) End_Column, 
       MAX([Type]) [Type]
FROM (
  SELECT *, SUM(flag) OVER (PARTITION BY [Row] ORDER BY [Column]) grp
  FROM (
    SELECT *, 
      CASE WHEN [Type] = LAG([Type]) OVER (PARTITION BY [Row] ORDER BY [Column]) THEN 0 ELSE 1 END flag
    FROM tablename
  ) t
) t
GROUP BY [Row], grp
ORDER BY [Row], grp
看。 结果:

您可以使用LAG和SUM窗口函数创建所需的组,然后进行聚合:

SELECT [Row], 
       MIN([Column]) Start_Column, 
       MAX([Column]) End_Column, 
       MAX([Type]) [Type]
FROM (
  SELECT *, SUM(flag) OVER (PARTITION BY [Row] ORDER BY [Column]) grp
  FROM (
    SELECT *, 
      CASE WHEN [Type] = LAG([Type]) OVER (PARTITION BY [Row] ORDER BY [Column]) THEN 0 ELSE 1 END flag
    FROM tablename
  ) t
) t
GROUP BY [Row], grp
ORDER BY [Row], grp
看。 结果:


这是一种缺口和孤岛问题。在这种情况下,最简单的方法可能是行号的差异:

select row, type, min(column), max(column)
from (select t.*,
             row_number() over (partition by row, type order by column) as seqnum_2,
             row_number() over (partition by row order by column) as seqnum
      from t
     ) t
group by row, type, (seqnum - seqnum_2)
order by row, min(column);
如果列是连续的,没有间隙,则可以进一步简化:

select row, type, min(column), max(column)
from (select t.*,
             row_number() over (partition by row, type order by column) as seqnum_2
      from t
     ) t
group by row, type, (column - seqnum_2)
order by row, min(column);
为什么这样做有效?若你们从列中减去一个递增序列,那个么结果是常数——当类型相同时


这是一种间隙和孤岛问题。在这种情况下,最简单的方法可能是行号的差异:

select row, type, min(column), max(column)
from (select t.*,
             row_number() over (partition by row, type order by column) as seqnum_2,
             row_number() over (partition by row order by column) as seqnum
      from t
     ) t
group by row, type, (seqnum - seqnum_2)
order by row, min(column);
如果列是连续的,没有间隙,则可以进一步简化:

select row, type, min(column), max(column)
from (select t.*,
             row_number() over (partition by row, type order by column) as seqnum_2
      from t
     ) t
group by row, type, (column - seqnum_2)
order by row, min(column);
为什么这样做有效?若你们从列中减去一个递增序列,那个么结果是常数——当类型相同时


是一个数字小提琴。

提问时,您需要提供一个最小的可重复示例。请参考以下链接:请提供以下内容:1 DDL和示例数据填充,即创建表和插入T-SQL语句。2您需要做什么,即逻辑和代码尝试在T-SQL中实现它。3期望输出,基于上述1中的样本数据。4您的SQL Server版本选择@@version;在提问时,您需要提供一个最小的可复制示例。请参考以下链接:请提供以下内容:1 DDL和示例数据填充,即创建表和插入T-SQL语句。2您需要做什么,即逻辑和代码尝试在T-SQL中实现它。3期望输出,基于上述1中的样本数据。4您的SQL Server版本选择@@version;我试着用我的数据来做这件事,结果成功了!非常感谢。我试图做一些类似的事情,但我甚至没有考虑将列和类型编号之间的差异分组。我尝试在我的数据上进行分组,结果成功了!非常感谢。我试着做一些类似的事情,但我甚至没有考虑将列和类型numberIt之间的差异分组,这让我有点难以理解为什么通过计算当前项和所有先前项的总和来计算顺序上的总和。这个想法很简单。当前类型对应于某个数字。如果类型不变,则编号相同。类型已更改-我们增加了数量。感谢您的实施。我有点难以理解为什么通过计算当前和以前所有项目的总和来计算订单的总和。这个想法很简单。当前类型对应于某个数字。如果类型不变,则编号相同。类型已更改-我们增加了数量。感谢您的实施