限制加入查询的结果

时间:2010-02-16 22:04:10

标签: sql tsql join

说我有以下表格:

|RefNumber| Charge| IssueDate|
------------------------------
|    00001|   40.0|2009-01-01|
|    00002|   40.0|2009-06-21|

|ID|RefNumber|Forename|   Surname|
---------------------------------
  1|    00001|     Joe|     Blogs|  
  2|    00001|   David|     Jones|
  3|    00002|    John|     Smith|
  4|    00002|    Paul|     Walsh|

我想从第一个表中选择refnumber,charge和issuedate然后加入refnumber到第二个表来检索forename和surname但只获得id最高的行。

结果如下:


|RefNumber| Charge| IssueDate|ID|Forename|   Surname|
-----------------------------------------------------
|    00001|   40.0|2009-01-01| 2|   David|     Jones|
|    00002|   40.0|2009-06-21| 4|    Paul|     Walsh|

我不确定将连接上的结果限制为仅返回第二个表中具有最高ID的记录。

4 个答案:

答案 0 :(得分:1)

我可能会加入一个子查询,该子查询只返回具有最高id的第二个表中的记录。

select a.RefNumber, a.Charge, a.IssueDate, b.ID, b.Forename, b.Surname
from References a inner join
    (select ID, RefNumber, ForeName, Surname from Names n1
        where n1.ID = (select top 1 n2.ID from Names n2 where n1.RefNumber = n2.RefNumber) ) b
    on a.RefNumber = b.RefNumber

答案 1 :(得分:1)

最灵活的写入方式(不需要相关子查询)是使用ROW_NUMBER(仅限SQL Server 2005+):

;WITH Names_CTE AS
(
    SELECT
        ID, RefNumber, Forename, Surname,
        ROW_NUMBER() OVER (PARTITION BY RefNumber ORDER BY ID) AS RowNum
    FROM Names
)
SELECT o.RefNumber, o.Charge, o.IssueDate, n.Forename, n.Surname
FROM Orders o
[INNER|LEFT] JOIN Names_CTE n
    ON n.RefNumber = o.RefNumber
WHERE n.RowNum = 1

请注意,如果您可以使用ROW_NUMBER代替MIN/MAX并不总是效率最高,只需要编写最简单的内容。

如果您运行的是SQL 2000,或者效率不高,则可以尝试MINMAX查询:

SELECT o.RefNumber, o.Charge, o.IssueDate, n.Forename, n.Surname
FROM Orders o
[INNER|LEFT] JOIN
(
    SELECT RefNumber, MIN(ID) AS MinID
    FROM Names
    GROUP BY RefNumber
) m
    ON m.RefNumber = o.RefNumber
[INNER|LEFT] JOIN Names n
    ON n.ID = m.MinID

有时这实际上更快,它在很大程度上取决于所使用的索引策略。

(编辑 - 这会获得带有最低 ID的行,这在大多数情况下会比获取最高 ID更快。如果您需要最高,请更改第一个查询ORDER BY ID DESC,第二个查询使用MAX代替MIN)。

答案 2 :(得分:0)

实际上你的子查询需要为每个重新编号选择最高的ID,所以看起来更像是这样:

select 
        a.RefNumber, a.Charge, a.IssueDate, b.BiggestID, b.Forename, b.Surname
from References a 
inner join
    (select
           RefNumber,
           max(ID) as BiggestID
     from Names
     group by
           RefNumber) b
    on a.RefNumber = b.RefNumber

希望有所帮助。 - 汤姆

答案 3 :(得分:0)

select nt.RefNumber, ct.Charge, ct.IssueDate, nt.ID, nt.Forename, nt.Surname
from NameTable nt
join ChargeTable ct on (ct.RefNumber = nt.RefNumber)
where nt.ID = (select MAX(nt2.id) 
               from NameTable nt2 
               where nt2.RefNumber = nt.RefNumber)
order by nt.ID