2010-05-11 46 views
1

我有兩個表在差不多更新完全相同的時間 - 我需要加入的日期時間列。SQL - 如何加入類似的(不是確切的)列

我已經試過這樣:

SELECT * 
FROM A, B 
WHERE ABS(DATEDIFF(second, A.Date_Time, B.Date_Time)) = (
    SELECT MIN(ABS(DATEDIFF(second, A.Date_Time, B2.Date_Time))) 
    FROM B AS B2 
) 

但它告訴我:

多個列中包含外部引用的被聚合表達式中指定。如果要彙總的表達式包含外部引用,那麼該外部引用必須是表達式中引用的唯一列。

我該如何加入這些表格?

回答

4

如何像(假設SQL 2005+):

With RankedItems As 
    (
    Select A.DateTime As ADateTime, B.DateTime As BDateTime 
     , ROW_NUMBER() OVER (PARTITION BY A.DateTime ORDER BY ABS(DateDiff(s, A.DateTime, B.DateTime))) As ItemRank 
    From A 
     Cross Join B 
    ) 
Select 
From RankedItems 
Where ItemRank = 1 

在我的解決方案,我用了很短的公共表表達式或CTE。在CTE中,我使用了排序函數(ROW_NUMBER),它可以計算CTE表達式中的每一行。 ROW_NUMBER函數將返回爲表A中的每個DateTime值提供一個順序整數,通過PARTITION BY A.DateTime子句按「緊密度」A.DateTime值到B.DateTime值的絕對值排序。因此,我使用Abs(DateDiff(s,A.DateTime, B.DateTime)併爲每個A.DateTime值選擇最高排名(排名= 1,又名「最接近」值),將排名「接近」。因爲ROW_NUMBER()函數將爲每個A.DateTime值返回一個唯一的數字列表,所以沒有關係。

+0

你能解釋一下這段代碼的工作原理嗎?我從來沒有見過很多這樣的構造。 – 2010-05-11 21:36:20

+0

@BlueRaja - 我已經擴展了我的答案以提供更多細節。 – Thomas 2010-05-11 23:14:19

+0

我最終在查詢中用'TOP 1 ... ORDER BY Date_Time'取代了'MIN',但是這個答案教會了我一些新的東西,並且幫助我解決了一個相關的問題(找到了一個特定列更改的行尊重上一行,按日期排序)。謝謝! – 2010-05-12 13:42:01

2

首先創建一個包含保存您計算的datediff的列的視圖,然後從中構建查詢可能會更好。

3

這是你想要的嗎?它會檢查1秒差

select * from 
A, b --use a join next time 
where A.Date_Time 
between DATEADD(s,-1,B.Date_Time) and DATEADD(s,1,B.Date_Time) 
+0

我想加入A行的每一行與最近的Date_Time值的B行。它不一定總是在1秒內 – 2010-05-11 20:28:44