如何检查 SQL 条记录是否按特定顺序排列

How to check if SQL records are in a specific order

我无法弄清楚如何检查 table 上的记录是否按特定顺序排列。简化的 table 设计本质上是这样的:

+------------+----------------+--------+
| ID (GUID)  |   StartDate    | NumCol |
+------------+----------------+--------+
| CEE8C17... | 8/17/2019 3:11 |     22 |
| BB22001... | 8/17/2019 3:33 |     21 |
| 4D40B12... | 8/17/2019 3:47 |     21 |
| 3655125... | 8/17/2019 4:06 |     20 |
| 3456CD1... | 8/17/2019 4:22 |     20 |
| 38BAF92... | 8/17/2019 4:40 |     19 |
| E60CBE8... | 8/17/2019 5:09 |     19 |
| 5F2756B... | 8/17/2019 5:24 |     18 |
+------------+----------------+--------+

ID 列是非顺序 GUID。输入数据时,table 默认排序在 StartDate 上。但是,我试图标记 NumCol 值不按降序排列的实例。 NumCol 值在相邻记录上可以相同,但最终它们必须降序。

+--------+
| NumCol |
+--------+
|     22 |
|    *20 | <- I want the ID where this occurs
|     21 |
|     20 |
|     20 |
|     19 |
|     19 |
|     18 |
+--------+

我已经尝试 LEFT JOIN 这个 table 本身,但似乎无法想出一个 ON 子句来给出正确的结果:

ON a.ID <> b.ID AND a.NumCol > b.NumCol

我还认为我可以使用 OFFSET n ROWS 将默认排序的 table 与对其执行 ORDER BY NumCol 的排序进行比较。我想不出任何有用的东西。

我需要一个适用于 SQL Server 和 SQL Compact 的解决方案。

这可能是最简单的:

select * from T t1
where NumCol < (select max(NumCol) from T t2 where t2.StartDate > t1.StartDate);

exists 版本可能更适合优化。

使用分析函数,您可以尝试这种方法,它可以在连续行的单调性中找到中断。它可能不会 return 您感兴趣的所有行:

with data as (
    select *, lag(NumCol) over (order by StartDate desc) as prevNumCol
    from T
)
select * from data where prevNumCol > NumCol;

这里有一个更好的解决方案,可能在您的两个环境中都不可用:

with data as (
    select *,
        max(NumCol) over (
            order by StartDate desc
            rows between unbounded preceding and current row
        ) as prevMax
    from T
)
select * from data where prevMax > NumCol;

有 EXISTS:

select t.* from tablename t
where exists (
  select 1 from tablename
  where numcol > t.numcol and startdate > t.startdate
)

或使用 row_number() window 函数:

select t.id, t.startdate, t.numcol
from (
  select *,
    row_number() over (order by startdate desc) rn1,
    row_number() over (order by numcol) rn2
  from tablename 
) t
where rn1 > rn2

参见demo