[英]For each unique record ID, return the most recent record of type Y iff there is a more recent record of type X
对于每个唯一的记录 ID,返回类型 Y 的最新记录当且仅当存在类型 X 的更新记录
为了使解释更容易,我将按 EventDate 降序排列记录,并只查看特定的记录 ID。 (最近在顶部。)
情况1
ID | 活动日期 | 类型 |
---|---|---|
1个 | 一些日期 | 其他(多条记录) |
1个 | 7月29日 | X |
1个 | 2月23日 | 是 |
1个 | 1月3日 | 是 |
1个 | 一些日期 | 其他(多条记录) |
类型 Y 的返回记录从 2 月 23 日开始(2 月 23 日与类型 X 的记录日期 1 月 1 日比较接近)
案例二
ID | 活动日期 | 类型 |
---|---|---|
2个 | 一些日期 | 其他(多条记录) |
2个 | 11 月 2 日 | X |
2个 | 10 月 31 日 | 是 |
2个 | 一些日期 | 其他的东西 |
2个 | 7月2日 | X |
2个 | 2月23日 | 是 |
2个 | 1月5日 | 是 |
2个 | 一些日期 | 其他的东西 |
返回类型 Y 的 2 月 23 日和类型 Y 的 10 月 31 日的记录。这些是分别在日期方面最接近类型 X 记录的记录。 (2 月 23 日的 y 型最接近 7 月 2 日的 X 型,10 月 31 日的 Y 型最接近 11 月 2 日的 X 型)
案例三
ID | 活动日期 | 类型 |
---|---|---|
3个 | 一些日期 | 其他(多条记录) |
3个 | 7月2日 | X |
3个 | 2月23日 | 是 |
3个 | 一些日期 | 其他的东西 |
3个 | 1月5日 | X |
3个 | 一些日期 | 其他的东西 |
返回 Feb 23 类型 Y 记录
案例四
ID | 活动日期 | 类型 |
---|---|---|
4个 | 一些日期 | 其他(多条记录) |
4个 | 10 月 15 日 | 是 |
4个 | 7月2日 | X |
5个 | 2月23日 | X |
5个 | 一些日期 | 其他的东西 |
5个 | 1月5日 | 是 |
5个 | 1 月 1 日 | 是 |
5个 | 一些日期 | 其他的东西 |
仅返回类型 Y 记录的 1 月 5 日。 就发生在类型 X 之前的日期而言,它最接近类型 X 的记录
SELECT
*
FROM
(
SELECT
*,
ROW_NUMBER() OVER ( PARTITION BY A.ID ORDER BY EventDate DESC ) AS pc
FROM
SOMETABLE AS "A"
INNER JOIN
(
SELECT
ID AS 'BID',
MIN(EventDate) AS 'OldestDate'
FROM
SOMETABLE
WHERE
TYPE = 'X'
GROUP BY
ID
) AS "B" ON A.ID = B.BID
WHERE
EventDate < OldestDate
AND
Type = 'Y'
) AS "FINAL"
在需要拉取多个类型 Y 的记录的情况下,这会失败,因为它“过滤掉”任何比类型 X 的 OLDEST 实例更新的记录。
如果给定的 X 值存在,此查询将采用最新的 Y 值。
SELECT
*
,ROW_NUMBER() OVER (PARTITION BY ID ORDER BY XDateTime ASC) AS 'Degree'
FROM
(SELECT
*
,ROW_NUMBER() OVER (PARTITION BY YDateTime ORDER BY XDateTime ASC) AS 'dc'
FROM
(SELECT
ID
,EventDateTime AS 'YDateTime'
,B.XDateTime
,DATEDIFF(SECOND, EventDateTime, B.XDateTime) AS 'Time'
,ROW_NUMBER() OVER (PARTITION BY B.XDateTime ORDER BY EventDateTime DESC) AS 'pc'
FROM vw_A6Productivity AS "A"
INNER JOIN
(SELECT
ID AS 'BID'
,EventDateTime AS 'XDateTime'
FROM TABLE
WHERE TYPE = 'X'
GROUP BY
ID
,EventDateTime
) AS "B"
ON A.ID= B.BID
WHERE
EventDateTime < XDateTime -- Inner join filters for Nulls automatically
AND STATUS = 'Y'
) AS "C"
WHERE
pc = 1
) AS "D"
WHERE dc = 1;
所以问题是寻找具有相同 ID 且密切发生的两种不同类型的事件。 不确定您是在 Y 之前寻找 X,在 X 之前寻找 Y,还是两者兼而有之。
我们可以将数据分为两组:
步骤 1. 准备数据
create table event (
id int,
event_date date,
type char(1));
insert into event
values
(1, '2022-01-01', 'X'),
(1, '2022-01-03', 'X'),
(1, '2022-01-05', 'Y'),
(1, '2022-01-07', 'Y'),
(1, '2022-01-09', 'X'),
(1, '2022-01-11', 'X'),
(1, '2022-01-15', 'Y');
第 2 步:加入并比较两个事件
with
event_x as (select id, type, event_date from event where type='X'),
event_y as (select id, type, event_date from event where type='Y'),
event_xy as (
select x.id,
x.event_date as x_event_date,
y.event_date as y_event_date,
datediff(x.event_date,y.event_date) as days_from_x_to_y
from event_x x
join event_y y
using (id))
select id,
x_event_date,
y_event_date,
days_from_x_to_y,
abs(days_from_x_to_y) as days_between_x_and_y
from event_xy
where 1 = 1
-- and days_from_x_to_y <=0 -- x happened after y
-- and days_from_x_to_y >=0 -- x happened before y
order by days_between_x_and_y asc;
我们得到:
id|x_event_date|y_event_date|days_from_x_to_y|days_between_x_and_y|
--+------------+------------+----------------+--------------------+
1| 2022-01-03| 2022-01-05| -2| 2|
1| 2022-01-09| 2022-01-07| 2| 2|
1| 2022-01-09| 2022-01-05| 4| 4|
1| 2022-01-01| 2022-01-05| -4| 4|
1| 2022-01-11| 2022-01-07| 4| 4|
1| 2022-01-03| 2022-01-07| -4| 4|
1| 2022-01-11| 2022-01-15| -4| 4|
1| 2022-01-11| 2022-01-05| 6| 6|
1| 2022-01-01| 2022-01-07| -6| 6|
1| 2022-01-09| 2022-01-15| -6| 6|
1| 2022-01-03| 2022-01-15| -12| 12|
1| 2022-01-01| 2022-01-15| -14| 14|
对 where 子句稍作改动,我们可以选择我们需要的 (x, y) 事件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.