2010-05-11 35 views
1

我有以下2個表:如何重寫長查詢?

items: 
id int primary key 
bla text 

events: 
id_items int 
num int 
when timestamp without time zone 
ble text 
composite primary key: id_items, num 

,並希望選擇每個項目最近的事件(最新的「何時」)。 我寫了一個請求,但我不知道它是否可以更有效地寫入。 同樣在PostgreSQL的存在與比較時間戳對象問題: 2010-05-08T10:00:00.123 == 2010-05-08T10:00:00.321 所以我選擇用 'MAX(NUM)' 有什麼想法如何使它更好?謝謝。

SELECT i.*, ea.* FROM items AS i JOIN 
(SELECT t.s AS t_s, t.c AS t_c, max(e.num) AS o FROM events AS e JOIN 
(SELECT DISTINCT id_item AS s, MAX(when) AS c FROM events GROUP BY s ORDER BY c) AS t 
ON t.s = e.id_item AND e.when = t.c GROUP BY t.s, t.c) AS tt 
ON tt.t_s = i.id JOIN events AS ea ON ea.id_item = tt.t_s AND ea.cas = tt.t_c AND ea.num = tt.o; 

編輯:已壞的數據,對不起,是我不好,但是感謝找到更好的SQL查詢

+0

注意:Postgres中沒有DATETIME類型,你可能是指TIMESTAMP。 – 2010-05-11 08:28:54

+0

好點:) 應該是「沒有時區的時間戳」 會編輯它 – pingi 2010-05-11 09:06:12

+1

什麼是「比較時間戳對象的問題」? – araqnid 2010-05-11 09:58:34

回答

0
SELECT (i).*, (e).* 
FROM (
     SELECT i, 
       (
       SELECT e 
       FROM events e 
       WHERE e.id_items = i.id 
       ORDER BY 
         when DESC 
       LIMIT 1 
       ) e 
     FROM items i 
     ) q 
0

如果您使用8.4:

select * from (
    select item.*, event.*, 
     row_number() over(partition by item.id order by event."when" desc) as row_number 
    from items item 
     join events event on event.id_items = item.id 
) x where row_number = 1 
0

對於本類型的連接,我更喜歡DISTINCT ON語法(example)。 這是一個PostgreSQL的擴展(不是SQL標準語法),但說到非常方便:

SELECT DISTINCT ON (it.id) 
it.*, ev.* 
FROM items it, events ev 
WHERE ev.id_items = it.id 
ORDER by it.id, ev.when DESC; 

你不能擊敗的是,在簡潔性和可讀性方面。

該查詢假定每個項目至少有一個事件。如果不是這樣,如果你希望所有 事件,你需要一個外部聯接:

SELECT DISTINCT ON (it.id) 
it.*, ev.* 
FROM items it LEFT JOIN events ev 
ON ev.id_items = it.id 
ORDER BY it.id, ev.when DESC; 

BTW:沒有「時間戳問題」在PostgreSQL,也許你應該更改標題。