2012-04-17 146 views
3

我有两个表:SQL服务器 - 连接两个表基于最近的日期

 A 
--------------- 
No. Name 
1  J.Smith 
2  R.Alan 
3.  D.Williams 


     B 
---------------------------- 
ID. Date  Address No.(FK from table A) 
1  10/03/01 blah blah 1 
2  08/02/05 blah blah 2 
3.  12/01/02 blah blah 3 
4.  03/07/11 blah blah 1 
5.  30/03/09 blah blah 2 

我想这两个表连接在一起基于从表B.最近的日期ommiting重名行例如,如果我使用左内连接将表A和B连接在一起,则将为J. Smith获取两行(基于表B中的第1行和第4行)。我想排除旧日期(表B中的第1行)。

我该怎么做?

编辑:

我需要包括从表B中的所有列

+0

什么版本的sql服务器? – Arion 2012-04-17 09:09:59

+0

使用SQL Server 2008 – user559142 2012-04-17 09:12:47

+1

'10/03/01'是什么日期? '2010日至01'? 'OCT-03-2001'? '10日至2001'? '10日至1901'? – 2012-04-17 09:57:37

回答

1

也许是这样的:

;WITH CTE 
AS 
(
    SELECT 
     ROW_NUMBER() OVER(PARTITION BY tblB.[No] ORDER BY tblB.[Date]) AS RowNbr, 
     tblB.* 
    FROM 
     B AS tblB 
) 
SELECT 
    * 
FROM 
    A AS tblA 
    LEFT JOIN CTE 
     ON tblA.No=CTE.No 
     AND CTE.RowNbr=1 
0
SELECT A.No 
    , A.Name 
    , C.Date 
    , C.Address 
    , C. ... 
FROM A 
LEFT JOIN 
    (SELECT Address , ... , No, Date, ROW_NUMBER() OVER(PARTITION BY No ORDER BY Date DESC) AS row 
     FROM B 
    ) C ON A.No = C.No 
WHERE C.row = 1 

WHERE COALESCE(C.row, 1) = 1 [if there is no link ,and you'll get Date NULL] 

编辑:如果你有很多列在B

SELECT A.No 
    , A.Name 
    , C.* (also row) 
FROM A 
LEFT JOIN 
    (SELECT * , ROW_NUMBER() OVER(PARTITION BY No ORDER BY Date DESC) AS row 
     FROM B 
    ) C ON A.No = C.No 
WHERE C.row = 1 
+0

好吧,这似乎工作,但如果表B有其他列,我想包括在我的SQL语句中不需要在分区? – user559142 2012-04-17 09:25:25

+0

您可以通过按日期排序来完成分区,并获取所有ID,然后从表B中获取所需的所有数据,之后您可以与表A进行连接。 – Zyku 2012-04-17 09:28:46

+0

实际上,表B中有许多其他列(举例来说)。如何在select语句中包含非分区列 – user559142 2012-04-17 09:49:04

1
WITH [max_dates] AS (
    SELECT [No], MAX([Date]) AS [Date] 
    FROM [TableB] 
    GROUP BY [No] 
) 
SELECT [a].[Name], [b].[Date] 
FROM [TableA] AS [a] 
JOIN [max_dates] AS [b] ON ([a].[No] = [b].[No]) 
ORDER BY [a].[No] ASC 
+0

一个缺点是,如果您需要来自B的任何其他数据,它必须进入CTE或B需要链接到SELECT语句此外。肯定适用于所问的问题。 – KMB 2012-04-17 11:48:15

0

尼斯使用CTE由罗里·亨特的,或者没有它:

SELECT [A].Name, [B].Date 
FROM [A] 
    INNER JOIN [B] 
     INNER JOIN 
     (-- build a limitation on B 
      SELECT No, MaxDate = Max(Date) 
      FROM [B] 
      GROUP BY No 
     ) BLimit 
      ON BLimit.No = B.No 
      AND BLimit.MaxDate = B.Date 
     ON B.No = A.No 

BLIMIT只允许最高日来仅通过对每个无(FK)作为限制器。并且B中的所有字段都可以用于查询,因为仅在使用BLimit时B发生了限制。