SQL - 在两个结果表上加入,重构的想法?

时间:2011-12-31 15:59:25

标签: sql postgresql join refactoring

这可能已经被问到了,但是StackOverflow是庞大的,并试图谷歌寻找足够实际帮助的东西是一场噩梦!

我最终得到了一个相当大的SQL查询,并且想知道SO是否可以指出我可能错过的更简单的方法。

我有一个名为usage的表格,其结构如下:

host    | character varying(32)       | 
usage   | integer                     | 
logtime | timestamp without time zone | default now()

我想获得MAX和MIN记录时间的使用值。在完成了我的一些旧教科书之后(因为我真正使用了SQL,已经有一段时间了),我最终得到了这个JOIN:

SELECT *
FROM (SELECT u.host,u.usage AS min_val,r2.min
  FROM usage u
  JOIN (SELECT host,min(logtime) FROM usage GROUP BY host) r2
  ON u.host = r2.host AND u.logtime = r2.min) min_table
NATURAL JOIN (SELECT u.host,u.usage AS max_val,r1.max
  FROM usage u
  JOIN (SELECT host,max(logtime) FROM usage GROUP BY host) r1
  ON u.host = r1.host AND u.logtime = r1.max) max_table
;

这似乎是一种混乱的方式,因为我基本上运行相同的查询两次,一次使用MAX,一次使用MIN。我可以通过执行SELECT usage,MAX(logtime),MIN(logtime) FROM ...在一个查询中获取两个logtime列,但我无法确定如何显示与两个不同记录对应的使用值。

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

使用PostgreSQL 9.1,您可以使用窗口功能(8.4 +):

SELECT DISTINCT
       u.host
      ,first_value(usage) OVER w AS first_usage
      ,last_value(usage) OVER w AS last_usage
FROM   usage u
WINDOW w AS (PARTITION BY host ORDER BY logtime, usage
             ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)

我按logtimeusage对分区进行排序,除了打破任何关系并达到稳定的结果。阅读window functions in the manual

有关更多解释和链接,您可能需要参考最近的相关答案herehere