仅返回一列中的日期与另一列中的日期最接近的行?
Posted
技术标签:
【中文标题】仅返回一列中的日期与另一列中的日期最接近的行?【英文标题】:Return only the row where the date in one column is closest to the date in another column? 【发布时间】:2021-06-04 19:54:29 【问题描述】:我正在处理一个查询,但它返回了一些重复的值,我只需要返回一列中的日期与另一列中的日期最接近的行。
我的查询如下所示:
SELECT p.Id, r.ReferralDate, s.SupervisionDate
FROM person p
INNER JOIN referral r on r.PersonId = p.Id
INNER JOIN supervision s on s.PersonId = p.Id
返回如下内容:
Id | Supervision Date | Referral Date |
---|---|---|
123 | 2015-09-30 | 2015-08-30 |
123 | 2020-02-30 | 2015-08-30 |
123 | 2020-06-30 | 2015-08-30 |
456 | 2010-06-30 | 2010-07-30 |
456 | 2005-06-30 | 2010-07-30 |
如何编写一个查询来返回最接近推荐日期的监督日期?这样最终的输出看起来像这样:
Id | Supervision Date | Referral Date |
---|---|---|
123 | 2015-09-30 | 2015-08-30 |
456 | 2010-06-30 | 2010-07-30 |
【问题讨论】:
【参考方案1】:在这种情况下,您可以使用两种方式来选择您需要的记录。
我更喜欢这种方式,因为它是非常有效的解决方案。我们按日期差异获取行顺序并选择最小日期差异。第一种方式,您可以选择要显示的列。这也是更通用的解决方案。
SELECT A.Id
, A.ReferalDate
, A.Supervision
FROM
(
SELECT
p.Id
, r.ReferalDate
, s.Supervision
,ROW_NUMBER() OVER (PARTITION BY p.Id ORDER BY DATEDIFF(DD,r.ReferalDate,s.Supervision) ASC) as [row_num]
FROM person p
INNER JOIN referral r
on r.pid = p.Id
INNER JOIN supervision s
on s.pid = p.Id
) AS A
WHERE A.row_num = 1
这样我们按日期差异排序并获得前 1 条记录。如果将此添加到 CTE 或派生表中,您仍然可以只返回您需要的列。此查询是特定于场景的,因为我们不考虑分区。
SELECT top 1
p.Id
, r.ReferalDate
, s.Supervision
,DATEDIFF(DD,r.ReferalDate,s.Supervision) as [date dif]
FROM person p
INNER JOIN referral r
on r.pid = p.Id
INNER JOIN supervision s
on s.pid = p.Id
ORDER BY [date dif] ASC
两种方式都返回相同的结果,因为我们的订单是在日期差异上下达的。
【讨论】:
【参考方案2】:这是一种方法:
select p.Id, r.ReferralDate, s.SupervisionDate from (
select p.Id, r.ReferralDate, s.SupervisionDate , row_number() over (partition by id order by abs(datediff(day , ReferralDate,SupervisionDate))) rn
from person p
join referral r on r.PersonId = p.Id
join supervision s on s.PersonId = p.Id
) t
where rn = 1
【讨论】:
【参考方案3】:另一种方式:
select ID, SUP from
( SELECT
p.Id 'ID',
r.ReferralDate 'REF',
s.SupervisionDate 'SUP',
min(julianday(s.SupervisionDate) - julianday(r.ReferralDate) ) 'diff'
FROM person p
INNER JOIN referral r on r.PersonId = p.Id
INNER JOIN supervision s on s.PersonId = p.Id
GROUP BY p.ID
)
这将根据要求返回 ID 和 SupervisionDate。
【讨论】:
除非我很困惑,否则这将总共返回 1 行,而不是每个 id 1 行。 @Andrew 你是绝对正确的,发帖人的例子只使用了 ID 123,所以我没有考虑到会有其他 ID。帖子会更新的,我的错。显示良好的采样日期有多重要。 有没有 julianday() 的替代方法?它在 SQL Server 中不起作用。 @JLo,抱歉,将您的问题读为 SQLite。对于 MSSQL,我相信您可以使用 DATEDIFF(day, firstdate, seconddate) 而不是朱利安日期之间的差异。然后只需选择其中的最小值。 这个答案使用的是 SQLLIte 中的一些函数 julianday()。以上是关于仅返回一列中的日期与另一列中的日期最接近的行?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Presto 中获取连续日期,其中一列中的开始日期和另一列中的结束日期