如何选择具有列的连续值的行

时间:2014-06-26 14:55:26

标签: sql sql-server sql-server-2005

我有一张如下表格

CREATE TABLE [dbo].[LINE](
[ID] [nvarchar](50) NOT NULL,
[LINE_NUM] [int] NOT NULL
) ON [PRIMARY]

insert into LINE select '01201301090100600004', '1'
insert into LINE select '01201301090100600004', '2'
insert into LINE select '01201301090100600004', '3'
insert into LINE select '01201301090100600004', '4'
insert into LINE select '01201301090100600005', '1'
insert into LINE select '01201301090100600005', '4'
insert into LINE select '01201301090100600005', '5'
insert into LINE select '01201301100045200002', '1'
insert into LINE select '01201301100045200002', '2'
insert into LINE select '01201301100045200002', '3'
insert into LINE select '01201301100081300008', '1'
insert into LINE select '01201301100081300008', '3'

我想选择LINE_NUM列连续的记录。它应该从1开始。所以我期待只选择下面的

   '01201301090100600004', '1'
   '01201301090100600004', '2'
   '01201301090100600004', '3'
   '01201301090100600004', '4'
   '01201301100045200002', '1'
   '01201301100045200002', '2'
   '01201301100045200002', '3'

我该怎么做?

编辑问题:

我正在寻找的是获取LINE_NUM以1开头的不同ID以及ID的多个LINE_NUM,然后检查它们是否是顺序的并检索这些ID' s ?

我用它来搞定它

SELECT id,
   m.line_num,
   m.new_line_num
FROM   (SELECT t.line_num AS old_line_num,
           t.*
    FROM   (SELECT t.*,
                   Row_number()
                     OVER (
                       partition BY clm_id
                       ORDER BY line_num ) AS new_line_num
            FROM   line t) t) m
WHERE  m.line_num <> m.new_line_num  

3 个答案:

答案 0 :(得分:2)

您可以使用row_number()执行此操作。如果值是连续的(比#34;连续&#34;更准确的术语),那么差异将是一个常数:

select id, line_num
from (select t.*,
             min(diff) over (partition by id) as mindiff,
             max(diff) over (partition by id) as maxdiff
      from (select t.*,
                   (line_num - row_number() over (partition by id order by line_num)) as diff
            from table t
           ) t
     ) t
where mindiff = maxdiff and mindiff = 1;

如果您只是想找到没有间隙的id,您甚至不需要窗口功能:

select t.id
from table t
group by t.id
having (max(line_num) - min(line_num) + 1 = count(distinct line_num));

答案 1 :(得分:0)

您可以使用ROW_NUMBER() OVER (ORDER BY ID)按ID列排序。然后使用它来检查下一行是否有Line_Num + 1

WITH CTE AS
(
    SELECT IdNum = ROW_NUMBER() OVER (ORDER BY ID), *
    FROM dbo.LINE
)
SELECT ID,LINE_NUM 
FROM CTE
WHERE (SELECT LINE_NUM FROM CTE c2
       WHERE c2.IdNum = CTE.IdNum + 1) = LINE_NUM + 1

Demo

答案 2 :(得分:0)

也许我们可以这样做

declare @Line  TABLE (
    [ID] [nvarchar](50) NOT NULL,
    [Line_NUM] [int] NOT NULL
    ) 

    insert into @Line select '01201301090100600004', '1'
    insert into @Line select '01201301090100600004', '2'
    insert into @Line select '01201301090100600004', '3'
    insert into @Line select '01201301090100600004', '4'
    insert into @Line select '01201301090100600005', '1'
    insert into @Line select '01201301090100600005', '4'
    insert into @Line select '01201301090100600005', '5'
    insert into @Line select '01201301100045200002', '1'
    insert into @Line select '01201301100045200002', '2'
    insert into @Line select '01201301100045200002', '3'
    insert into @Line select '01201301100081300008', '1'
    insert into @Line select '01201301100081300008', '3'
    ;WITH CTE AS 
    (
    select ID,Line_NUM,RN=ROW_NUMBER()OVER(PARTITION by ID ORDER BY Line_NUM ) from @Line
    ),CTE2 AS
    (
    Select distinct 
    ID,Line_NUM,RR = ROW_NUMBER()OVER(PARTITION by ID ORDER BY  Line_NUM )
    from CTE 
    WHERE Line_NUM = RN 
    GROUP BY ID,Line_NUM,RN 
    )
    ,CTE3 AS
    (
    Select C.id,C.Line_NUM,RANK() OVER(Order By c.id) as t_index FROM CTE2 C
    GROUP BY C.ID,C.RR,c.Line_NUM
    )

    Select ID,Line_Num from 
    (Select DISTINCT cc.ID,CC.Line_NUM,COUNT(CC.t_index)OVER (Partition by cc.ID)RS from CTE3  CC)Z
      WHERE RS > 1