如何检索每个不同 ID 的最早日期和状态
Posted
技术标签:
【中文标题】如何检索每个不同 ID 的最早日期和状态【英文标题】:How Can I Retrieve The Earliest Date and Status Per Each Distinct ID 【发布时间】:2020-11-09 14:47:42 【问题描述】:我一直在尝试编写一个查询来完善这个实例,但似乎无法做到这一点,因为我仍然收到重复。希望我能得到有关如何解决此问题的帮助。
SELECT DISTINCT
1.Client
1.ID
1.Thing
1.Status
MIN(1.StatusDate) as 'statdate'
FROM
SAMPLE 1
WHERE
[]
GROUP BY
1.Client
1.ID
1.Thing
1.status
我的输出如下
Client Id Thing Status Statdate
CompanyA 123 Thing1 Approved 12/9/2019
CompanyA 123 Thing1 Denied 12/6/2019
因此,尽管查询正在执行我的要求并显示每个状态的最小状态日期,但我只想要第一个状态日期。我有大约 30k 行要过滤,所以任何不运行的查询都会使查询过载并且不会运行。任何帮助将不胜感激
【问题讨论】:
用您正在使用的数据库标记您的问题。 【参考方案1】:使用窗口函数:
SELECT s.*
FROM (SELECT s.*,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY statdate) as seqnum
FROM SAMPLE s
WHERE []
) s
WHERE seqnum = 1;
这将返回每个 id 的第一行。
【讨论】:
我想要每个 ID 的第一行,而不是客户端。我将如何利用上面的查询来做到这一点?抱歉,我对 SQL 很陌生,上面的内容让我有些困惑。 将分区更改为 ID 而不是客户端,然后 @Ziegler199 。认为非唯一 ID 似乎是一个奇怪的设计选择。【参考方案2】:使用你觉得更舒服/理解的任何一个:
SELECT
*
FROM
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY statusdate) as rn
FROM sample
WHERE ...
) x
WHERE rn = 1
一种工作方式是按 StatusDate 的顺序对所有行进行编号,每次 ID 更改时从 1 重新开始编号。如果你这样收集所有的数字 1,那么你就有了一组“第一条记录”
或者可以协调一个MIN:
SELECT
*
FROM
sample s
INNER JOIN
(SELECT ID, MIN(statusDate) as minDate FROM sample WHERE ... GROUP BY ID) mins
ON s.ID = mins.ID and s.StatusDate = mins.MinDate
WHERE
...
这个准备了所有 ID 和最小日期的列表,然后将其连接回主表。因此,您可以找回在分组操作期间丢失的所有数据;你不能在一个小组中同时“保留数据”和“丢弃数据”;如果您不仅仅按 ID 分组,您将获得更多组(如您所见)。如果您仅按 ID 分组,则会丢失其他列。没有任何方法可以说“GROUP BY id,并获取 MIN 日期,并且还从与最小日期相同的行中获取所有其他数据”而不执行“按 id 分组,获取最小日期,然后加入此数据集回主数据集以获取该最小日期的其他数据”。如果您尝试在一个分组中完成所有操作,您将失败,因为您要么必须按更多列分组,要么对 SELECT 中的其他数据使用聚合函数,这会将您的数据混合在一起;分组完成后,“同一行的其他数据”的概念就消失了
请注意,如果两条记录的最短日期相同,这可能会返回重复的行。 ROW_NUMBER 表单不会返回重复记录,但如果两条记录具有相同的最小 StatusDate,那么您将获得哪条记录是随机的。要强制一个特定的,ORDER BY more stuff 这样你就可以确定哪个会以 1 结束
【讨论】:
以上是关于如何检索每个不同 ID 的最早日期和状态的主要内容,如果未能解决你的问题,请参考以下文章
对于每个 ID,返回 r 中开始列的最早日期和结束列的最新日期
如何在不同时间获得相同ID的每个部分的最小日期? - SQL 服务器