sql - 拉取日期记录在当前状态是第一个
问题描述
我有一个包含当前记录信息的表和一个历史表。每次更新记录时,都会在当前表中创建一条新记录,并将前一条记录移动到历史表中。我想返回当前客户端、连接、状态首次设置的日期。关键是连接可能会移出并返回当前状态,因此我不能只是一般地在历史表中查找与 ConnectionStatus 表中的客户端、连接、状态相匹配的第一个日期。在下面的示例中,我希望从历史记录表中的第二条记录返回 DateChanged - 1-19-2021。
连接状态
客户 | 联系 | 地位 | 日期更改 |
---|---|---|---|
A B C D | 1234 | 4 | 2021 年 1 月 27 日 |
连接状态历史
客户 | 联系 | 地位 | 日期更改 |
---|---|---|---|
A B C D | 1234 | 4 | 2021 年 1 月 24 日 |
A B C D | 1234 | 4 | 2021 年 1 月 19 日 |
A B C D | 1234 | 3 | 2021 年 1 月 16 日 |
A B C D | 1234 | 3 | 2021 年 1 月 12 日 |
A B C D | 1234 | 4 | 2021 年 1 月 8 日 |
解决方案
这有点棘手。一种方法是获取与另一个状态相关联的最新日期,然后只选择大于该日期的行:
select csh.client, csh.connection, csh.status, min(csh.date)
from (select t.*,
max(case when most_recent_status <> status then date end) over (partition by client, connection) as other_date
from (select csh.*,
first_value(csh.status) over (partition by client, connection order by date desc) as most_recent_status
from ConnectionStatusHistory csh
) csh
) csh
where date > other_date or other_date is null
group by client, connection, status;
更聪明的方法使用row_number()
:
select client, connection, status, min(date)
from (select csh.*,
row_number() over (partition by client, connection order by date desc) as seqnum,
row_number() over (partition by client, connection, status order by date desc) as seqnum_s
from ConnectionStatusHistory csh
) csh
where seqnum = seqnum_s
group by client, connection, status;
这更令人费解。但是如果您查看子查询的结果,您会看到它seqnum
从最近的 1 开始枚举所有行。然后seqnum_s
按状态枚举行。仅当状态为最新状态时,这些值才相等。
推荐阅读
- java - 以秒为单位添加时区的转换后的 unix 时间戳在 Android 模拟器上提供了真正的本地日期时间,但在真实设备中却没有?
- html - 如何在图像响应式顶部制作文本块?
- android - 带有 FragmentContainerView 的 Null NavHostFragment/NavController
- c++ - 使用 LoadToolbarEx 解决异常以及正常与大图像计数之间的差异
- c - 在带有位域的结构中使用带有位域的结构?
- oracle - SQL Developer 不显示 XML
- vba - 在文档中按文件路径插入图片以匹配通用名称 MS Access VBA 的数百页
- android - 闪屏中的闪屏
- c# - Xamarin Forms iOS IsSpellCheckEnabled 不起作用
- bash - 使用 xargs 运行多个命令 - for 循环