SQL 服务器:在 table 中查找两列不连续的行
SQL Server: Find rows in table where both columns not sequential
我有一个 table 数据如下所示:
pK Customer DateTime1 DateTime2
1 6 2016-04-01 00:00:00.000 2016-10-09 00:00:00.000
2 6 2016-07-01 00:00:00.000 2016-10-21 00:00:00.000
3 6 2016-10-01 00:00:00.000 2016-10-20 00:00:00.000
我想查找在订购 DateTime1 时相应的 DateTime2 值(按客户 ID 筛选时)不遵循相同顺序的行。
所以在上面的例子中,我想找到 pK 为 3 的行,因为当 DateTime1 按升序排序时,DateTime2 不大于第 2 行中的 DateTime2。
看起来与这个问题类似,但它处理的是项目的顺序而不是不等式:
TSQL check if specific rows sequence exists
我尝试使用 CTE 语句的一个版本
这似乎是 row_number()
的一个很好的应用:
select t.*
from (select t.*,
row_number() over (partition by customer order by datetime1) as seqnum_1,
row_number() over (partition by customer order by datetime2) as seqnum_2
from t
) t
where seqnum_1 <> seqnum_2;
但这会 return 所有排序错误的行,基于全局排序(在本例中为 pk 2 和 3)。
您只需要在给定行上改变方向的位置。为此,使用 lag()
:
select t.*
from (select t.*,
lag(datetime1) over (partition by customer order by pk) as prev_dt1,
lag(datetime2) over (partition by customer order by pk) as prev_dt2
from t
) t
where (dt1 > prev_dt1 and dt2 <= prev_dt2) or
(dt1 < prev_dt1 and dt2 >= prev_dt2);
Declare @YourTable table (pK int,Customer int,DateTime1 datetime,DateTime2 datetime)
Insert Into @YourTable values
(1,6,'2016-04-01 00:00:00.000','2016-10-09 00:00:00.000'),
(2,6,'2016-07-01 00:00:00.000','2016-10-21 00:00:00.000'),
(3,6,'2016-10-01 00:00:00.000','2016-10-20 00:00:00.000')
;with cte as (
Select *,Flg=Row_Number() over (Partition By Customer Order By DateTime1) - Row_Number() over (Partition By Customer Order By DateTime2)
From @YourTable
)
Select pK
,Customer
,DateTime1
,DateTime2
From cte
Where Flg>0
Returns
pK Customer DateTime1 DateTime2
3 6 2016-10-01 00:00:00.000 2016-10-20 00:00:00.000
我有一个 table 数据如下所示:
pK Customer DateTime1 DateTime2
1 6 2016-04-01 00:00:00.000 2016-10-09 00:00:00.000
2 6 2016-07-01 00:00:00.000 2016-10-21 00:00:00.000
3 6 2016-10-01 00:00:00.000 2016-10-20 00:00:00.000
我想查找在订购 DateTime1 时相应的 DateTime2 值(按客户 ID 筛选时)不遵循相同顺序的行。
所以在上面的例子中,我想找到 pK 为 3 的行,因为当 DateTime1 按升序排序时,DateTime2 不大于第 2 行中的 DateTime2。
看起来与这个问题类似,但它处理的是项目的顺序而不是不等式: TSQL check if specific rows sequence exists
我尝试使用 CTE 语句的一个版本
这似乎是 row_number()
的一个很好的应用:
select t.*
from (select t.*,
row_number() over (partition by customer order by datetime1) as seqnum_1,
row_number() over (partition by customer order by datetime2) as seqnum_2
from t
) t
where seqnum_1 <> seqnum_2;
但这会 return 所有排序错误的行,基于全局排序(在本例中为 pk 2 和 3)。
您只需要在给定行上改变方向的位置。为此,使用 lag()
:
select t.*
from (select t.*,
lag(datetime1) over (partition by customer order by pk) as prev_dt1,
lag(datetime2) over (partition by customer order by pk) as prev_dt2
from t
) t
where (dt1 > prev_dt1 and dt2 <= prev_dt2) or
(dt1 < prev_dt1 and dt2 >= prev_dt2);
Declare @YourTable table (pK int,Customer int,DateTime1 datetime,DateTime2 datetime)
Insert Into @YourTable values
(1,6,'2016-04-01 00:00:00.000','2016-10-09 00:00:00.000'),
(2,6,'2016-07-01 00:00:00.000','2016-10-21 00:00:00.000'),
(3,6,'2016-10-01 00:00:00.000','2016-10-20 00:00:00.000')
;with cte as (
Select *,Flg=Row_Number() over (Partition By Customer Order By DateTime1) - Row_Number() over (Partition By Customer Order By DateTime2)
From @YourTable
)
Select pK
,Customer
,DateTime1
,DateTime2
From cte
Where Flg>0
Returns
pK Customer DateTime1 DateTime2
3 6 2016-10-01 00:00:00.000 2016-10-20 00:00:00.000