我正在查看带有两个表的SQL Server 2008数据库,每个表都有一个PK(INT)列和一个DateTime列。
表之间没有明确的关系,除了我知道应用程序具有成对插入数据库的启发式趋势,每行中有一行,DateTimes似乎永远不会完全匹配,但通常非常接近。 / p>
我试图通过在另一个表中找到最接近的匹配DateTime来匹配每个表中的PK。每个PK只能用于此匹配。
这样做的最佳方式是什么?
编辑:对不起,请在底部找到一些示例输入和所需的输出。
+-------+-------------------------+
| t1.PK | t1.DateTime |
+-------+-------------------------+
| 1 | 2016-08-11 00:11:03.000 |
| 2 | 2016-08-11 00:11:08.000 |
| 3 | 2016-08-11 11:03:00.000 |
| 4 | 2016-08-11 11:08:00.000 |
+-------+-------------------------+
+-------+-------------------------+
| t2.PK | t2.DateTime |
+-------+-------------------------+
| 1 | 2016-08-11 11:02:00.000 |
| 2 | 2016-08-11 00:11:02.000 |
| 3 | 2016-08-11 22:00:00.000 |
| 4 | 2016-08-11 11:07:00.000 |
| 5 | 2016-08-11 00:11:07.000 |
+-------+-------------------------+
+-------+-------+-------------------------+-------------------------+
| t1.PK | t2.PK | t1.DateTime | t2.DateTime |
+-------+-------+-------------------------+-------------------------+
| 1 | 2 | 2016-08-11 00:11:03.000 | 2016-08-11 00:11:02.000 |
| 2 | 5 | 2016-08-11 00:11:08.000 | 2016-08-11 00:11:07.000 |
| 3 | 1 | 2016-08-11 11:03:00.000 | 2016-08-11 11:02:00.000 |
| 4 | 4 | 2016-08-11 11:08:00.000 | 2016-08-11 11:07:00.000 |
+-------+-------+-------------------------+-------------------------+
答案 0 :(得分:2)
加入t1.DateTime
和t2.DateTime
之间DATEDIFF最低(以秒为单位)的行。
答案 1 :(得分:1)
您可以通过将表1与表2交叉连接来获得您正在寻找的结果,然后根据Tab Alleman的建议获得日期的差异(以秒为单位)。接下来的步骤是使用ROW_NUMBER()
函数对每个匹配进行排名。最后一步是仅选择Rank = 1
行。
以下示例演示了如何使用示例数据:
DECLARE @t1 TABLE
(
ID INT PRIMARY KEY
,[DateTime] DATETIME
);
DECLARE @t2 TABLE
(
ID INT PRIMARY KEY
,[DateTime] DATETIME
)
INSERT INTO @t1
(
ID
,[DateTime]
)
VALUES
(1 ,'2016-08-11 00:11:03.000'),
(2 ,'2016-08-11 00:11:08.000'),
(3 ,'2016-08-11 11:03:00.000'),
(4 ,'2016-08-11 11:08:00.000');
INSERT INTO @t2
(
ID
,[DateTime]
)
VALUES
(1, '2016-08-11 11:02:00.000'),
(2, '2016-08-11 00:11:02.000'),
(3, '2016-08-11 22:00:00.000'),
(4, '2016-08-11 11:07:00.000'),
(5, '2016-08-11 00:11:07.000');
WITH CTE_DateDifference
AS
(
SELECT t1.ID AS T1_ID
,t2.ID AS T2_ID
,t1.[DateTime] AS T1_DateTime
,t2.[DateTime] AS T2_DateTime
,ABS(DATEDIFF(SECOND, t1.[DateTime], t2.[DateTime])) AS Duration -- Determine the difference between the dates in seconds.
FROM @t1 t1
CROSS JOIN @t2 t2
),CTE_RankDateMatch
AS
(
SELECT T1_ID
,T2_ID
,T1_DateTime
,T2_DateTime
,ROW_NUMBER() OVER (PARTITION BY T1_ID ORDER BY Duration) AS [Rank] -- Rank each match, the row numbers generated will be order based on the duration between the dates. Thus rows with a number of 1will be the closest match between the two tables.
FROM CTE_DateDifference
)
-- Finally select out the rows with a Rank equal to 1.
SELECT *
FROM CTE_RankDateMatch
WHERE [Rank] = 1