【问题标题】:Aggregate function with Date on PostgresPostgres上带有日期的聚合函数
【发布时间】:2010-11-13 18:39:30
【问题描述】:

我的 SQL 有点生疏了,也许你可以帮我解决这个查询。

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

桌票

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

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

last_message - bigint 

(和之前一样)

table ticket_messages

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

我正在寻找一些分组或聚合函数来从表中获取所有数据,并尝试计算最后一条和第一条之间花费的时间,还尝试显示第一条和最后一条消息的日期。


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

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

我认为它做到了......

【问题讨论】:

    标签: postgresql select aggregate-functions


    【解决方案1】:

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

    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;
    

    【讨论】:

      【解决方案2】:

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

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

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

      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。)

      您现在可以平均这些间隔。你不能平均日期,因为日期不能加在一起也不能分开;平均包括求和和除法。区间可加可分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-09-22
        • 2020-08-31
        • 1970-01-01
        • 1970-01-01
        • 2018-06-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多