2016-10-07 5 views
1

私は、PK(INT)列とDateTime列を持つ2つのテーブルを持つSQL Server 2008データベースを見ています。2つのテーブル間での(ダーティ)ペアのDateTimes

私はアプリケーションが対になってデータベースに挿入するヒューリスティックな傾向があることを除いて、テーブル間に明示的な関係はなく、DateTimesは正確には一致しないと思われますが、

私は、他のテーブルに最も近い一致DateTimeを見つけることによって、各テーブルのPKをバックアップすることを試みています。各PKは、このマッチングのために一度しか使用できません。

これを行うにはどのような方法が最適ですか?

EDIT:申し訳ありませんが、入力例と出力例の一番下にあります。

+-------+-------------------------+ 
| 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 | 
+-------+-------+-------------------------+-------------------------+ 
+2

'T1からはDATEADD(分-1、t2.datetimecolumn)とDATEADD(分、1、t2.datetimecolumn)間t1.datetimecolumnにT2に参加します;' –

+0

@AaronBertrand迅速な対応をありがとう、申し訳ありませんが、私は十分に明確ではなかった。私はいくつかのサンプル入力と所望の出力で質問を明確にしました。 – Maarx

答えて

2

t1.DateTimet2.DateTime間(秒)最低DATEDIFFと行にJOIN。

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 
関連する問題