2017-03-17 95 views
2

哇这个问题真的很难简明扼要地制定。所以,这里的数据:查找具有相关最大日期行列匹配值的表的行吗?

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

我想回到所有Person行,其最近期的Activityfoo

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

谢谢!

+0

你尝试过什么?你使用哪个dbms? – jarlh

+0

我正在使用SQLite,但如果绝对必要,可以使用MySQL。我实际上是通过flask-sqlalchemy来做这件事的,我当然可以用代码来过滤它,但是我觉得SQL会更快。 – Rick

+0

我试着修改这个答案,但无法让它工作得很正确:http://stackoverflow.com/questions/7745609/sql-select-only-rows-with-max-value-on-a-column – Rick

回答

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服务器/甲骨文(乐趣)

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

这似乎工作得很好,除了两个活动日期相同的情况。 (未说明的)意图是找到“欺骗”但不“禁止”的人。我的数据有点肮脏,我可能只是把它清理干净。 – Rick

+1

@Rick查看编辑 – JohnHC

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') 
相关问题