LEFT JOIN最大/顶部

时间:2012-07-25 03:15:52

标签: sql sql-server sql-server-2008 tsql

我有两个表,我正在尝试运行查询以返回每个人的最大(或最高)事务。我应该注意,我不能改变表结构。相反,我只能提取数据。

+-----------+
| id | name |
+-----------+
| 42 | Bob  |
| 65 | Ted  |
| 99 | Stu  |
+-----------+

交易(没有主键)

+---------------------------------+
| person     | amount | date      |
+---------------------------------+
| 42         | 3      | 9/14/2030 |
| 42         | 4      | 7/02/2015 |
| 42         | *NULL* | 2/04/2020 |
| 65         | 7      | 1/03/2010 |
| 65         | 7      | 5/20/2020 |  
+---------------------------------+

最终,对于我想要返回最高金额的每个人。如果这不起作用,那么我想查看日期并返回最近的日期。

所以,我希望我的查询返回:

+----------------------------------------+
| person_id  | name | amount | date      |
+----------------------------------------+
| 42         | Bob  | 4      | 7/02/2015 | (<- highest amount)
| 65         | Ted  | 7      | 5/20/2020 | (<- most recent date)
| 99         | Stu  | *NULL* | *NULL*    | (<- no records in Transactions table)
+----------------------------------------+

SELECT People.id, name, amount, date
FROM People
LEFT JOIN (
    SELECT TOP 1 person_id
    FROM Transactions
    WHERE person_id = People.id
    ORDER BY amount DESC, date ASC
)
ON People.id = person_id

我无法弄清楚我做错了什么,但我知道这是错的。任何帮助将非常感激。

1 个答案:

答案 0 :(得分:3)

你几乎就在那里,但由于Transaction表中有重复的Id,所以你需要使用Row_number()函数删除它们 试试这个:

With cte as 
 (Select People,amount,date ,row_number() over (partition by People 
                                  order by amount desc, date desc) as row_num
  from Transac )
 Select * from People as a 
 left join cte as b
 on a.ID=b.People
 and b.row_num=1

结果位于Sql Fiddle

编辑:来自MSDN的Row_number()

Returns the sequential number of a row within a partition of a result set, 
starting at 1 for the first row in each partition.

分区用于对结果集进行分组,并使用Over by子句

Determine the partitioning and ordering of the rowset before the
associated window function is applied.