如何在SQL Server中获取与记录日期最近的日期?
我有以下数据结构: 表A:如何在SQL Server中获取与记录日期最近的日期?,sql,sql-server,Sql,Sql Server,我有以下数据结构: 表A: ID | RequestNumber | Date ----+-----------------+----------- 1 | 1 | 2017/09/27 2 | 1 | 2018/06/02 RequestNumber | Serial | Date ---------------+----------+----------- 1 | 1 |
ID | RequestNumber | Date
----+-----------------+-----------
1 | 1 | 2017/09/27
2 | 1 | 2018/06/02
RequestNumber | Serial | Date
---------------+----------+-----------
1 | 1 | 2017/09/27
1 | 2 | 2017/09/27
1 | 6 | 2018/06/03
1 | 7 | 2018/06/03
1 | 8 | 2018/06/03
表B:
ID | RequestNumber | Date
----+-----------------+-----------
1 | 1 | 2017/09/27
2 | 1 | 2018/06/02
RequestNumber | Serial | Date
---------------+----------+-----------
1 | 1 | 2017/09/27
1 | 2 | 2017/09/27
1 | 6 | 2018/06/03
1 | 7 | 2018/06/03
1 | 8 | 2018/06/03
我们可以看到,距离表A第一行最近的日期是表B中的2017/09/27,距离第二行最近的日期是表B中的2018/06/03
所以
我需要查询表a
中的每一行,以及表B
中距离表a
中记录最近的所有行(这意味着第一条记录应返回2条记录,第二条记录应返回3条记录)
预期结果将是:
ID | RequestNumber | Serial | Date
----+-----------------+----------+------------
1 | 1 | 1 | 2017/09/27
1 | 1 | 2 | 2017/09/27
2 | 1 | 6 | 2018/06/03
2 | 1 | 7 | 2018/06/03
2 | 1 | 8 | 2018/06/03
提前感谢此查询将满足您的要求。它将TableA
连接到RequestNumber
上的TableB
,然后连接到TableB
和TableA
之间的最小DATEDIFF
值表,确保我们只得到结果中最接近的日期:
SELECT a.ID, a.RequestNumber, b.Serial, b.Date
FROM TableA a
JOIN TableB b ON b.RequestNumber = a.RequestNumber
JOIN (SELECT a.ID AS ID, MIN(ABS(DATEDIFF(day, b.Date, a.Date))) AS days
FROM TableA a
JOIN TableB b ON b.RequestNumber = a.RequestNumber
GROUP BY a.ID) c ON c.ID = a.ID AND c.days = ABS(DATEDIFF(day, b.Date, a.Date))
输出:
ID RequestNumber Serial Date
1 1 1 27/09/2017 09:30:00
1 1 2 27/09/2017 09:30:00
2 1 6 03/06/2018 09:30:00
2 1 7 03/06/2018 09:30:00
2 1 8 03/06/2018 09:30:00
ID RequestNumber Serial Date
1 1 1 27/09/2017 00:00:00
1 1 2 27/09/2017 00:00:00
2 1 6 03/06/2018 00:00:00
2 1 7 03/06/2018 00:00:00
2 1 8 03/06/2018 00:00:00
另一种可能的方法是使用左连接和稠密秩()。我假设您想要最接近且大于的日期:
CREATE TABLE #TableA (
ID int,
RequestNumber int,
[Date] date
)
CREATE TABLE #TableB (
RequestNumber int,
Serial int,
[Date] date
)
INSERT INTO #TableA (ID, RequestNumber, [Date])
VALUES
(1, 1, '2017-09-27'),
(2, 1, '2018-06-02')
INSERT INTO #TableB (RequestNumber, Serial, [Date])
VALUES
(1, 1, '2017-09-27'),
(1, 2, '2017-09-27'),
(1, 6, '2018-06-03'),
(1, 7, '2018-06-03'),
(1, 8, '2018-06-03'),
(1, 9, '2018-06-05'),
(1, 10, '2018-06-07')
; WITH cte AS (
SELECT
a.ID,
a.RequestNumber,
b.Serial,
b.[Date],
DENSE_RANK() OVER (PARTITION BY a.ID, a.RequestNumber ORDER BY a.ID, a.RequestNumber, b.[Date]) AS rn
FROM #TableA a
LEFT JOIN #TableB b ON (a.RequestNumber = b.RequestNumber) AND (a.[Date] <= b.[Date])
)
SELECT
ID,
RequestNumber,
Serial,
[Date]
FROM cte
WHERE rn = 1
ORDER BY ID, RequestNumber
这将为您提供所需的日期,尽管我认为您实际上没有为所需输出中的日期正确指定较小的日期项
Select * from table B
left join table A
on
B.requestNumber=A.requestNumber
and B.date >=A.Date;
这是使用横向联接的好地方(关键字apply
):
是一个dbfiddle。你试过什么吗?@PrashantPimpale我不知道。如果你想在左边显示id,你可以改进我上面的查询,选择a.id,b.*。