2010-02-16 138 views
2

说我有如下表:上加入查询限制结果

 
|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,从第一台充issuedate然后refnumber加入到第二个表检索的名字及姓氏,但只得到最高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的记录结果。

回答

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 ISN如果您可以使用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)。

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

'TOP 1'只会返回*一个*行 - 您只会记录具有最高ID的refnumber值的记录,并且只有一个refnumber值。 – 2010-02-16 22:27:30

+0

糟糕。需要更多层次的嵌套... – tvanfosson 2010-02-16 22:37:03

0

其实你的子查询需要选择每个refnumber最高的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 

希望有所帮助。 -Tom

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