2010-05-11 263 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,也许你应该更改标题。