我有以下数据:
tracking_num | 状态 |
---|---|
ABC | 迟到了 |
防御 | 迟到了 |
防御 | 准时 |
防御 | 准时 |
防御 | 准时 |
GHI | 准时 |
我需要以下输出:
tracking_num | 状态 | 预计 |
---|---|---|
ABC | 迟到了 | 迟到了 |
防御 | 迟到了 | 迟到了 |
防御 | 准时 | 迟到了 |
防御 | 准时 | 迟到了 |
防御 | 准时 | 迟到了 |
GHI | 准时 | 准时 |
我需要按跟踪号码进行分区,以查看是否有任何“迟到”值。如果存在迟到值,则该追踪号码被视为迟到,即使有其他条目显示“准时”(在本例中为追踪号码 DEF)。
准时追踪号码的重复计数/所有追踪号码的重复计数:1/3 = 33%
你能帮我用 SQL 实现这一点吗 - 我不确定要使用哪个窗口函数。 row_number 或通过跟踪编号对分区进行计数,状态只会给我一个行级别,而不是给我状态值。
谢谢!
有多种方法可以做到这一点,但一种方法是使用
min
作为窗口函数:
SELECT tracking_num, status, min(status) OVER (PARTITION BY tracking_num) expected
FROM tracking
由于“late”按字母顺序小于“ontime”,因此如果分区中存在“late”,则它是最小值。
这适用于您的样本数据,但它对
status
的可能值做出假设。
另一种选择是在
exists
子句中使用 select
和子查询,例如:
SELECT tracking_num, status,
CASE WHEN exists (SELECT * FROM tracking t2 WHERE t2.tracking_num = t1.tracking_num AND t2.status = 'late') THEN 'late' else status END expected
FROM tracking t1
如果迟到/准时是
status
的唯一可能值,则其行为应与之前的答案相同,但这专门查找“迟到”,并且不会对 status
的其他可能值做出假设。
您可以看到这两个选项的Fiddle。