2012-08-29 128 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