2012-08-29 131 views
2

我应该能够做到这一点,但大脑似乎已经回炉SQL子查询和分组

数据库是Postgres的

表结构很简单,只需四列说事:

位置,用户,活动,日期时间

我需要按位置进行排序,并输出发生的每个活动的最新发生次数。我不知道提前哪些活动是

喜欢的东西

 
Location User Activity DateTime 
London  Fred A   08-29-2012 
London  Fred B   08-27-2012 
Paris  John A   08-29-2012 
Tokyo  Fred A   08-17-2012 
Tokyo  Jane D   08-29-2012 

感谢乡亲

+2

?每个位置?每个用户?那是样本开始的数据还是期望的结果? –

+0

“按位置排序”是什么意思? – Ariel

+0

如果两个事件同时发生,会发生什么?即DateTime是唯一的? – Ariel

回答

4

最快方式是可能与DISTINCT ON

SELECT DISTINCT ON (location, activity) 
     location, activity, datetime, usr 
FROM tbl 
ORDER BY location, activity, datetime DESC, usr; -- usr only to break ties 

短形式与位置参数:

SELECT DISTINCT ON (1 ,2) 
     location, activity, datetime, usr 
FROM tbl 
ORDER BY 1, 2, 3 DESC, 4; 

此结合排序并减少不同的行中一个操作。 更多细节,解释和基准在this related answer

user是保留字。不要实际使用它作为列名。我用usr代替。

如果表现应该是至关重要的,如下面的指数将使区别:整体活动的最新发生

CREATE INDEX tbl_multi_idx ON tbl (location, activity, datetime DESC, usr); 
+1

这当然很好,避免了重复,但运行速度明显慢于@arial的方法。优雅简单的解决方案 - 由于速度并不重要,我认为这就是我将使用的那个 –

+0

@EricT:这很有趣,谢谢。创建添加到我的答案中的多列索引后,它是否仍然较慢? (应该对这两个问题都有好处。)我了解,表现对你来说并不重要,但我会非常感兴趣。你会介意在表格的两个特征和两个查询的表现上留下一两行粗略的数字吗?有没有索引?也许作为一个单独的答案,而不是一个更好的可读性评论。在此处放置评论,所以如果您这样做,我会收到通知... –

+0

对不起@Erwin Brandstetter我很乐意提供帮助,但我在由第三方管理的受限访问设备上运行此操作 - 我只能读取访问权限,因此可以不要添加索引。它虽然像魅力一样工作,并节省了我们工作人员的一小时工作时间。 –

0
SELECT 
    Location, 
    User 
    Activity 
    DateTime 
From 
    myTable a 
    INNER JOIN 
    (SELECT Location, User, Max(DateTime) as DateTime FROM myTable GROUP BY Location, User) b 
    ON a.Location = b.Location AND a.User = b.User AND a.DateTime = b.DateTime 
2
SELECT * FROM table JOIN (
    SELECT Activity, Location, Max(DateTime) DateTime FROM table 
    GROUP BY Activity, Location 
) m USING (Activity, Location, DateTime) 

最佳没有完全理解你的问题我可以回答。 PostgreSQL中

+0

是的,这对我很有用 –

0
select t1.location, t1.user, m.activity, m.datetime 
from table1 t1 inner join 
(select activity, max(datetime) datetime from table1 group by activity) m 
on t1.activity = m.activity and t1.datetime = m.datetime 
order by t1.location asc