查找不连续的运行值

时间:2016-04-13 23:08:47

标签: sql sql-server tsql

我有一个像下面附带的SQL表

+-----+------------+-------+-----+
| ID  |    Name    | Start | End |
+-----+------------+-------+-----+
| 100 | Road one   |     0 | 244 |
| 101 | Road two   |     0 | 300 |
| 101 | Road two   |   300 | 329 |
| 101 | Road two   |   329 | 400 |
| 101 | Road two   |   400 | 380 |
| 102 | Road three |     0 | 120 |
| 102 | Road three |   122 | 175 |
| 102 | Road three |   175 | 222 |
+-----+------------+-------+-----+

我需要查找所有正在运行的StartEnd值,这些值对于每个唯一ID都不是连续的。

在上面的示例中,380小于400,这是不正确的,而122大于120,这也是不正确的,因为它应该是120(之前的End值)。

我需要一个sql脚本来突出显示这些值。

帮助表示赞赏

3 个答案:

答案 0 :(得分:1)

如果您使用的是SQL Server 2012及更高版本,并且可以使用LAG功能,则可以使用以下查询

设置数据

create table #t (ID int, Name varchar(20), Start int , [End] int)

insert into #t values
( 100 , 'Road one'   ,     0 , 244 ),
( 101 , 'Road two'   ,     0 , 300 ),
( 101 , 'Road two'   ,   300 , 329 ),
( 101 , 'Road two'   ,   329 , 400 ),
( 101 , 'Road two'   ,   400 , 380 ),
( 102 , 'Road three' ,     0 , 120 ),
( 102 , 'Road three' ,   122 , 175 ),
( 102 , 'Road three' ,   175 , 222 )

查询

with cte as (
  select ID, Name, Start, [End]
  , LAG([End]) over (partition by ID order by ID, Start, [End]) PrevEnd
  from #t
)
select ID, Name, Start, [End]
from cte
where Start <> PrevEnd or [End] < Start

结果

+-----+------------+-------+-----+
| ID  |    Name    | Start | End |
+-----+------------+-------+-----+
| 101 | Road two   |   400 | 380 |
| 102 | Road three |   122 | 175 |
+-----+------------+-------+-----+

答案 1 :(得分:0)

试试这个:

--this select row | 102 | Road three |     0 | 120 |
SELECT * 
FROM table AS t1 
WHERE NOT Exists (SELECT 1 FROM table AS t2 WHERE t2.start = t1.end AND t2.id = t1.id)
AND Exists (SELECT 1 FROM table AS t2 WHERE t2.start > t1.end AND t2.id = t1.id)

--this select row| 102 | Road three |   122 | 175 |
SELECT * 
FROM table AS t1 
WHERE NOT Exists (SELECT 1 FROM table AS t2 WHERE t2.end = t1.start AND t2.id = t1.id)
AND t1.start <> 0

答案 2 :(得分:0)

以下条件是如果id的前一行存在,那么必须有前一行具有相同的结尾:

select t.*
from t
where end < start or
      (not exists (select 1 from t t2 where t2.id = t.id and t2.end = t.start) and
       exists (select 1 from t t2 where t2.id = t.id and t2.start < t.start)
      );

这涵盖了您问题的可能性。我不确定它是否涵盖所有可能性。