MySQL中最新订单状态的SQL查询
Posted
技术标签:
【中文标题】MySQL中最新订单状态的SQL查询【英文标题】:SQL query for latest Order Status in MySQL 【发布时间】:2021-05-13 06:03:58 【问题描述】:我们正在跟踪我们的运输合作伙伴通过他们触发的 webhook 发送的订单状态。 Webhook 每次触发时都会添加一行,因此每个订单都有多行与之关联。
表的结构 enter image description here
我们正在尝试创建一个 sql 查询以获取以下内容
查找最后收到的“awb”行。获取该行中的 current_status。如果current_status
是“PICKUP EXCEPTION
”、“OUT FOR PICKUP
”、“PICKUP RESCHEDULED
”中的任何一个,则找到该特定“awb”的这些状态第一次出现的行
检查 awb 的这些状态第一次出现和最后一次出现之间的天数
并输出相差超过 2 天的 awb。
这是我能够创建的查询。
WITH ranked_order_status AS (
SELECT os.*,
datediff(
now() ,
first_value(recived_at) over (partition by awb order by recived_at asc)
) as diff,
ROW_NUMBER() OVER (PARTITION BY awb ORDER BY recived_at desc) AS rn
FROM order_status AS os where current_status in ('PICKUP EXCEPTION', 'OUT FOR PICKUP', 'PICKUP RESCHEDULED')
)
SELECT * FROM ranked_order_status WHERE rn = 1 and diff > 2
不幸的是,这向我显示了所有具有这些状态的行的 awb,而不仅仅是那些最后收到的当前状态为“PICKUP EXCEPTION
”、“OUT FOR PICKUP
”、“PICKUP RESCHEDULED
”的awb
知道如何编辑吗?
【问题讨论】:
如果不包括示例数据,您可能无法得到答案。 @TimBiegeleisen 在此处添加示例数据的最佳方式是什么?我有 .sql 文件。而且它不是太大。截至目前 5000 行 你可以使用db-fiddle.com 【参考方案1】:所以如果我理解正确的话,这应该是一个使用 RANK() 的分析函数的明确案例。
这将是我对您提到的约束的方法:
WITH t1 AS (
SELECT
os.*,
FIRST_VALUE(os.received_at) OVER(PARTITION BY os.awb ORDER BY os.received_at) AS first_received_at
FROM order_status AS os
WHERE os.current_status IN ('PICKUP EXCEPTION', 'OUT FOR PICKUP', 'PICKUP RESCHEDULED')
),
t2 AS (
SELECT
RANK() OVER (PARTITION BY t1.awb ORDER BY t1.received_at DESC) AS reverse_event_sequence,
DATE_DIFF(t1.received_at, t1.first_received_at, DAY) AS day_diff
t1.*
FROM t1
),
final AS (
SELECT *
FROM t2
WHERE t2.day_diff > 2 AND t2.reverse_event_sequence = 1
)
SELECT * FROM final
基本上,您希望首先获取每行的 received_at 的第一个值,然后您希望对每个 awb 的所有事件进行排名并按降序排列以始终将最后一个事件作为 rank=1,然后您对日期差异应用所需的约束:)
我不得不提一下,没有数据样本也无济于事。并且希望对我的方法有任何反馈:)
【讨论】:
忘了提到函数的语法可能会有所不同(例如 date_diff()),因为我是在 StandardSQL 而不是 mysql 上编写的。很抱歉! 排名将是一个不错的选择。会试试这个。 嗨@lenoldvaz 你终于发现它有用了吗?想知道:D【参考方案2】:您可以通过两种方式从最近的行中枚举行:
按 awb 分区,按接收顺序降序 按 awb 和状态分区,并按收到的降序排序对于每个 awb 的最后状态,它们之间的差异将为零。你可以选择这个然后聚合:
select awb, current_status,
min(received_at), max(received_at)
from (select os.*,
row_number() over (partition by awb order by received_at desc) as seqnum,
row_number() over (partition by awb, current_status order by received_at desc) as seqnum_2
from order_status os
) os
where seqnum = seqnum_2 and
current_status in ('PICKUP EXCEPTION', 'OUT FOR PICKUP', 'PICKUP RESCHEDULED')
group by awb, current_status
having max(received_at) > min(received_at) + interval 2 day;
【讨论】:
以上是关于MySQL中最新订单状态的SQL查询的主要内容,如果未能解决你的问题,请参考以下文章