views:

95

answers:

3

I have two tables which get updated at almost the exact same time - I need to join on the datetime column.

I've tried this:

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
)

But it tells me:

Multiple columns are specified in an aggregated expression containing an outer reference. If an expression being aggregated contains an outer reference, then that outer reference must be the only column referenced in the expression.

How can I join these tables?

+2  A: 

It might be better to first create a view that contains a column holding your computed datediff, and then construct a query from that.

Robert Harvey
+3  A: 

Is this what you want? It will check for 1 second difference

    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)
SQLMenace
I want join every row of A with the row of B that has the nearest Date_Time value. It will not necessarily always be within 1-second
BlueRaja - Danny Pflughoeft
+2  A: 

How about something like (assuming 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

In my solution, I'm using a common-table expression or CTE for short. In the CTE, I'm using a ranking function (ROW_NUMBER) which calculates for each row in the CTE expression. The ROW_NUMBER function will return provide a sequential integer for each DateTime value in table A via the PARTITION BY A.DateTime clause ordered by the absolute value of the "closeness" A.DateTime value to the B.DateTime value. Thus, I'm ranking the "closeness" using Abs(DateDiff(s,A.DateTime, B.DateTime) and choosing the highest rank (rank = 1, aka "closest" value) for each A.DateTime value. It will not matter if there is a tie as the ROW_NUMBER() function will return a unique list of numbers for each A.DateTime value.

Thomas
Could you perhaps explain how this code works? I have never seen a lot of these constructs before.
BlueRaja - Danny Pflughoeft
@BlueRaja - I've expanded my answer to provide more detail.
Thomas
I ended up just replacing `MIN` with a `TOP 1 ... ORDER BY Date_Time` in my query, but this answer taught me something new and helped me with a related problem (finding all rows in which a particular column changed with respect to the previous row, when ordered by date-time). Thank you!
BlueRaja - Danny Pflughoeft