我有一个有两列的表格。第一个是自动增量
ID
列,第二个是 datetime
列,其中下一个数据应该在上一个数据的未来。我需要选择不正确的值。
示例:
身份证 | 时间戳 |
---|---|
1 | 2022-10-10 |
2 | 2022-10-11 |
3 | 2022-10-12 |
4 | 2022-10-13 |
5 | 2022-08-01 |
6 | 2022-08-02 |
7 | 2022-08-03 |
8 | 2022-10-14 |
9 | 2022-10-15 |
我只想选择那些行,其中先前的日期对它们来说是未来的日期。
所以从上面的例子来看,我的结果应该是第 5,6,7 行。
我尝试使用自连接和 LAG/LEAD 函数来做到这一点,但在这种情况下我应该知道这些行的数量。就我而言,它可以是任意数量的不符合模式的行
您可以使用自连接和不等式条件表达式来做到这一点:
SELECT DISTINCT t0.*
FROM [table] t0
INNER JOIN [table] t1 ON t1.ID < t0.ID AND t1.TimeStamp > t0.TimeStamp
您可以使用 MAX 来代替:
select *
from (
select *, max(timestamp) over(order by id) as maxVal
from (
VALUES (1, N'2022-10-10')
, (2, N'2022-10-11')
, (3, N'2022-10-12')
, (4, N'2022-10-13')
, (5, N'2022-08-01')
, (6, N'2022-08-02')
, (7, N'2022-08-03')
, (8, N'2022-10-14')
, (9, N'2022-10-15')
) t (ID,TimeStamp)
) x
where x.maxVal > x.TimeStamp
此检查确保之前的 ID 不高于当前 ID 并输出:
身份证 | 时间戳 | 最大值 |
---|---|---|
5 | 2022-08-01 | 2022-10-13 |
6 | 2022-08-02 | 2022-10-13 |
7 | 2022-08-03 | 2022-10-13 |
提出此类问题时,提供 DDL/DML 会很有帮助。使用您的示例数据:
DECLARE @Table TABLE (ID INT IDENTITY, TimeStamp DATE);
INSERT INTO @Table (TimeStamp) VALUES
('2022-10-10'), ('2022-10-11'), ('2022-10-12'), ('2022-10-13'),
('2022-08-01'), ('2022-08-02'), ('2022-08-03'), ('2022-10-14'),
('2022-10-15');
使用这个:
SELECT *
FROM (
SELECT ID, TimeStamp, MAX(TimeStamp) OVER (ORDER BY ID) AS mTimeStamp
FROM @Table
) a
WHERE TimeStamp < mTimeStamp;
身份证 | 时间戳 | m时间戳 |
---|---|---|
5 | 2022-08-01 | 2022-10-13 |
6 | 2022-08-02 | 2022-10-13 |
7 | 2022-08-03 | 2022-10-13 |
这里我们使用窗口函数
MAX
来查找按 ID
列排序的最大日期。然后,使用外部查询,我们可以将 TimeStamp
与此 MAX
值进行比较,并确定当前行是否小于窗口最大值。