MySQL window 函数获取该组状态相同的两个日期之间的差异
MySQL window function get difference between two dates where status is same on that group
我想做的事情:
查找 'awb' 的最后收到的行。获取该行中的 current_status。如果 current_status 是 'PICKUP EXCEPTION'、'OUT FOR PICKUP'、'PICKUP RESCHEDULED' 中的任何一个,则针对该特定 'awb' 找到这些状态首次出现的行
检查'awb'的那些STATUSES第一次出现和最后一次出现之间的天数,并输出相差超过2天的'awbs'。
我做了什么:
WITH ranked_order_status AS (
SELECT os.*,
ROW_NUMBER() OVER (PARTITION BY awb ORDER BY STR_TO_DATE(recived_at,'%m/%d/%y %T') desc) AS occurance
FROM order_status AS os
),
filtered_last_occurance_in_list as (
select * from ranked_order_status where occurance=1 and current_status in ('PICKUP EXCEPTION', 'OUT FOR PICKUP', 'PICKUP RESCHEDULED')
),
all_awb_with_last_status_in_list as
(
select * from order_status os2 where awb in (select awb from filtered_last_occurance_in_list) order by awb
)
select id, recived_at, awb,current_status from all_awb_with_last_status_in_list
当前输出:
id |recived_at |awb |current_status |
----|-------------|--------------|------------------|
2413|5/7/21 6:13 | 1091108643160|OUT FOR PICKUP |
2414|5/7/21 6:14 | 1091108643160|OUT FOR PICKUP |
2501|5/7/21 10:55 | 1091108643160|PICKUP EXCEPTION |
2503|5/7/21 11:13 | 1091108643160|PICKUP EXCEPTION |
1337|4/30/21 7:44 |14325421720410|OUT FOR PICKUP |
1399|4/30/21 17:39|14325421720410|PICKUP EXCEPTION |
1476|5/1/21 6:09 |14325421720410|PICKUP RESCHEDULED|
1500|5/1/21 11:09 |14325421720410|PICKUP EXCEPTION |
77|4/22/21 7:18 |19041127718646|OUT FOR PICKUP |
121|4/22/21 11:17|19041127718646|PICKUP EXCEPTION |
81|4/22/21 7:18 |19041128001310|OUT FOR PICKUP |
124|4/22/21 11:18|19041128001310|PICKUP EXCEPTION |
83|4/22/21 7:18 |19041128018585|OUT FOR PICKUP |
125|4/22/21 11:18|19041128018585|PICKUP EXCEPTION |
979|4/27/21 12:19|19041129734005|PICKUP EXCEPTION |
1334|4/30/21 6:48 |19041130453211|OUT FOR PICKUP |
1372|4/30/21 11:19|19041130453211|PICKUP EXCEPTION |
1534|5/1/21 18:47 |19041130453211|PICKUP EXCEPTION |
1483|5/1/21 7:18 |19041130642631|OUT FOR PICKUP |
1490|5/1/21 8:18 |19041130642631|PICKUP EXCEPTION |
1688|5/3/21 10:47 |19041130642631|PICKUP EXCEPTION |
预期结果: 假设 awb = 1091108643160,我需要使用 (5/7/21 11:13 - 5 创建一个名为 delay 的新列/7/21 10:55) = 18m
id recived_at awb current_status
2413|5/7/21 6:13 | 1091108643160|OUT FOR PICKUP |
2414|5/7/21 6:14 | 1091108643160|OUT FOR PICKUP |
2501|5/7/21 10:55 | 1091108643160|PICKUP EXCEPTION | -> this is first occurrence of same status
2503|5/7/21 11:13 | 1091108643160|PICKUP EXCEPTION | -> this is last row
calculate date difference between last row of a awb and first occurrence of that (status and awb)
WITH cte AS ( SELECT DISTINCT
awb,
FIRST_VALUE(current_status) OVER (PARTITION BY awb ORDER BY date DESC) current_status
FROM source )
SELECT awb, DATEDIFF(MAX(date), MIN(date))
FROM source
JOIN cte USING (awb, current_status)
GROUP BY awb
我想做的事情:
查找 'awb' 的最后收到的行。获取该行中的 current_status。如果 current_status 是 'PICKUP EXCEPTION'、'OUT FOR PICKUP'、'PICKUP RESCHEDULED' 中的任何一个,则针对该特定 'awb' 找到这些状态首次出现的行 检查'awb'的那些STATUSES第一次出现和最后一次出现之间的天数,并输出相差超过2天的'awbs'。
我做了什么:
WITH ranked_order_status AS (
SELECT os.*,
ROW_NUMBER() OVER (PARTITION BY awb ORDER BY STR_TO_DATE(recived_at,'%m/%d/%y %T') desc) AS occurance
FROM order_status AS os
),
filtered_last_occurance_in_list as (
select * from ranked_order_status where occurance=1 and current_status in ('PICKUP EXCEPTION', 'OUT FOR PICKUP', 'PICKUP RESCHEDULED')
),
all_awb_with_last_status_in_list as
(
select * from order_status os2 where awb in (select awb from filtered_last_occurance_in_list) order by awb
)
select id, recived_at, awb,current_status from all_awb_with_last_status_in_list
当前输出:
id |recived_at |awb |current_status |
----|-------------|--------------|------------------|
2413|5/7/21 6:13 | 1091108643160|OUT FOR PICKUP |
2414|5/7/21 6:14 | 1091108643160|OUT FOR PICKUP |
2501|5/7/21 10:55 | 1091108643160|PICKUP EXCEPTION |
2503|5/7/21 11:13 | 1091108643160|PICKUP EXCEPTION |
1337|4/30/21 7:44 |14325421720410|OUT FOR PICKUP |
1399|4/30/21 17:39|14325421720410|PICKUP EXCEPTION |
1476|5/1/21 6:09 |14325421720410|PICKUP RESCHEDULED|
1500|5/1/21 11:09 |14325421720410|PICKUP EXCEPTION |
77|4/22/21 7:18 |19041127718646|OUT FOR PICKUP |
121|4/22/21 11:17|19041127718646|PICKUP EXCEPTION |
81|4/22/21 7:18 |19041128001310|OUT FOR PICKUP |
124|4/22/21 11:18|19041128001310|PICKUP EXCEPTION |
83|4/22/21 7:18 |19041128018585|OUT FOR PICKUP |
125|4/22/21 11:18|19041128018585|PICKUP EXCEPTION |
979|4/27/21 12:19|19041129734005|PICKUP EXCEPTION |
1334|4/30/21 6:48 |19041130453211|OUT FOR PICKUP |
1372|4/30/21 11:19|19041130453211|PICKUP EXCEPTION |
1534|5/1/21 18:47 |19041130453211|PICKUP EXCEPTION |
1483|5/1/21 7:18 |19041130642631|OUT FOR PICKUP |
1490|5/1/21 8:18 |19041130642631|PICKUP EXCEPTION |
1688|5/3/21 10:47 |19041130642631|PICKUP EXCEPTION |
预期结果: 假设 awb = 1091108643160,我需要使用 (5/7/21 11:13 - 5 创建一个名为 delay 的新列/7/21 10:55) = 18m
id recived_at awb current_status
2413|5/7/21 6:13 | 1091108643160|OUT FOR PICKUP |
2414|5/7/21 6:14 | 1091108643160|OUT FOR PICKUP |
2501|5/7/21 10:55 | 1091108643160|PICKUP EXCEPTION | -> this is first occurrence of same status
2503|5/7/21 11:13 | 1091108643160|PICKUP EXCEPTION | -> this is last row
calculate date difference between last row of a awb and first occurrence of that (status and awb)
WITH cte AS ( SELECT DISTINCT
awb,
FIRST_VALUE(current_status) OVER (PARTITION BY awb ORDER BY date DESC) current_status
FROM source )
SELECT awb, DATEDIFF(MAX(date), MIN(date))
FROM source
JOIN cte USING (awb, current_status)
GROUP BY awb