Postgres上的Date聚合函数

时间:2009-07-24 15:02:13

标签: postgresql select aggregate-functions

我的SQL很生气,也许你可以帮我解决这个问题。

我有这两个表用于票据系统(我省略了一些字段):

表格门票

id - bigint
subject - text
user_id - bigint
closed - boolean
first_message - bigint 

(外键,用于下一个表的id)

last_message - bigint 

(与之前相同)

table ticket_messages

creation_date

我需要查询已关闭的票证,并平均在第一个消息creation_date和最后一个消息creation_date之间花费的时间。这就是我到目前为止所做的:

SELECT t.id, t.subject, tm.creation_date
FROM tickets AS t
INNER JOIN ticket_messages AS tm
ON tm.id = t.first_message
OR tm.id = t.last_message
WHERE t.closed = true

我正在寻找一些group by或aggregate函数来从表中获取所有数据,并尝试计算在last和first之间花费的时间,同时尝试显示第一条和最后一条消息的日期。


更新我在第二个表中添加了内部联接而不是“或”,现在我得到了两个日期,我可以从我的应用程序中找到总和:

SELECT t.id, t.subject, tm.creation_date, tm2.creation_date
FROM tickets AS t
INNER JOIN ticket_messages AS tm
ON tm.id = t.first_message
INNER JOIN ticket_messages as tm2
ON tm2.id = t.last_message
WHERE t.closed = true

我认为这样做了......

2 个答案:

答案 0 :(得分:1)

这样的事情应该可以让nr天过去。您可能需要将其放在子查询中,以便从“票证”中轻松提取更多字段。

SELECT t.id,AVG(tlast.creation_date - tfirst.creation_date)
  FROM tickets AS t
INNER JOIN ticket_messages AS tfirst
  ON tm.id = t.first_message
INNER JOIN ticket_messages AS tlast
  ON tm.id = t.last_message
WHERE t.closed = true
GROUP BY t.id

可能会导致(未经测试......),例如

select t.id,t.subject,sub.nr_days 
FROM (
  SELECT t.id,AVG(tlast.creation_date - tfirst.creation_date) as nr_days
    FROM tickets AS t
  INNER JOIN ticket_messages AS tfirst
    ON tm.id = t.first_message
  INNER JOIN ticket_messages AS tlast
    ON tm.id = t.last_message
  WHERE t.closed = true
  GROUP BY t.id ) AS sub
INNER JOIN tickets AS t
  ON sub.id = t.id;

答案 1 :(得分:1)

您正尝试将两个查询合并为一个,尝试从两个表中获取三行数据中的数据。两者都需要修复。

首先,您不应尝试将汇总数据(例如平均值)与单个项目的详细信息混合在一起 - 您需要单独查询。您可以这样做,但输出是重复的,因此是浪费的(组中的所有单个项目都具有相同的聚合数据)。

其次,您需要查找给定故障单的第一条消息和最后一条消息。因此,该查询是:

SELECT t.id, t.subject, tm1.creation_date as start, tm2.creation_date as end,
       tm2.creation_date - tm1.creation_date as close_interval
  FROM            tickets AS t
       INNER JOIN ticket_messages AS tm1 ON t.last_message = tm1.id
       INNER JOIN ticket_messages AS tm2 ON t.last_message = tm2.id
 WHERE t.closed = true

这为每个结果行提供了三行数据 - 根据需要。计算出的值应该是一个区间类型 - 假设PostgreSQL实际上有这种类型。 (在Informix中,对于合适的n,类型实际上是INTERVAL DAY(n),例如9。)

现在可以平均这些间隔。您无法平均日期,因为日期不能一起添加且无法分割;平均包括求和和除法。间隔可以添加和分割。