查找具有相关最大日期行列匹配值的表行?

时间:2017-03-17 08:49:20

标签: sql greatest-n-per-group

哇,这个问题很难简明扼要地制定出来。所以,这是数据:

Person:
+----+---------+
| ID | Name    |
+----+---------+
|  1 | Bob     |
|  2 | Alice   |
|  3 | Greg    |
|  4 | Lisa    |
+----+---------+

Activity:
+----+----------+------------+----------+
| ID | PersonID | Date       | Activity |
+----+----------+------------+----------+
|  1 | 1        | 2017-03-01 | foo      |
|  2 | 1        | 2017-03-02 | bar      |
|  3 | 2        | 2016-12-01 | foo      |
|  4 | 3        | 2017-01-15 | foo      |
+----+----------+------------+----------+

我想返回最近PersonActivity的所有foo行。

Return:
+----+---------+
| ID | Name    |
+----+---------+
|  2 | Alice   |
|  3 | Greg    |
+----+---------+

谢谢!

2 个答案:

答案 0 :(得分:3)

的MySQL

select P3.*
from 
(
select PersonID, max(Date) as mDate
from Activity
group by PersonID
) a1
inner join Activity A2
  on A2.PersonID = A1.PersonID
  and A2.Date = A1.mDate
inner join Person P3
  on P3.ID = A2.PersonID
where A2.Activity = 'Foo'
and not exists (select 1 -- This is for those who did both on one day
                from Activity A4 
                where A4.Activity = 'Bar'
                and A4.PersonID = A1.PersonID
                and A4.Date = A1.mDate)

对于SQL server / Oracle(为了好玩)

with CTE as
(
select A1.*, row_number() over(partition by PersonID order by Date desc) as r_ord
from Activity A1
)
select P2.*
from Person P2
inner join CTE 
  on CTE.PersonID = P2.ID
where CTE.r_ord = 1
and CTE.Activity = 'Foo'

答案 1 :(得分:1)

select * from Person where ID in 
(select PersonID from (select Top 1 * from Activity where PersonID = Person.ID order by Activity.Date desc) Tmp where Tmp.Activity <> 'bar')