MySQL从多个表中选择值,这取决于最新值

时间:2014-10-01 23:24:11

标签: mysql select

我有以下三个表来查看小型Web应用程序中的支持票证,但我需要一些帮助来获取我需要的数据。

表1(票):

user_ID  site_ID  support_ID  timestamp            priority  title
  12       25         3       2014-09-26  14:09:25    0      A Test Row
  12       26         4       2014-09-27  09:41:18    0      A 2nd Test Row

表2(ticket_reply):

reply_ID support_ID user_ID  support_reply             reply_timestamp
  3          3         12    some really boring text   2014-09-26 14:09:25
  4          3         25    some really boring reply  2014-09-26 15:35:18
  5          4         12    some really boring text   2014-09-27 09:41:18

表3(ticket_status):

ticket_status_ID support_ID status_ID  status_timestamp
        3            3          40     2014-09-26 14:09:25
        4            3          41     2014-09-26 15:35:18
        5            4          40     2014-09-27 09:41:18

第一张表格包含关键票证信息,第二张表格包含对相应票证的任何回复,第三张表格跟踪状态的变化(状态保存在另一张表格中,但不需要其他任何内容)

我需要做的是获取最新状态为== 40的票数,如果大于0,请获取最新回复以及第一张表中的数据。

我尝试了多种方法,但我被卡住了。不要把它们粘贴在这里,因为它们可能会让人感到困惑,我怀疑它们是否接近。

3 个答案:

答案 0 :(得分:3)

这个很棘手,但这是一个适合你的解决方案。

此查询将获取最新status_ID为40的所有故障单的最新support_reply值。

SELECT
    ticket_status_ID,
    support_ID,
  status_ID,
  status_timestamp,
  reply_ID,
  support_reply,
  reply_timestamp,
  `timestamp` ticket_timestamp,
  `priority` ticket_priority,
  title
FROM (
    SELECT * FROM (
        SELECT * FROM (
        SELECT
            ticket_status.ticket_status_ID,
            ticket_status.support_ID,
            ticket_status.status_ID,
            ticket_status.status_timestamp,
            ts1.reply_ID,
            ts1.user_ID,
            ts1.support_reply,
            ts1.reply_timestamp
            FROM
            ticket_status
            INNER JOIN (SELECT * FROM ticket_reply ORDER BY reply_timestamp DESC) ts1 ON ts1.support_ID = ticket_status.support_ID
            GROUP BY support_ID, status_ID
            ORDER BY status_timestamp DESC
        ) ts2
        GROUP BY ts2.support_ID
    ) ts3
    INNER JOIN (SELECT support_ID as `ticket_support_ID`, site_ID, `timestamp`, priority, title FROM ticket) ts4 ON ts4.ticket_support_ID = ts3.support_ID
    WHERE ts3.status_ID = 40
) ts5

答案 1 :(得分:1)

你可以尝试这个:

SELECT t.*, tr.support_reply, ts.status_timestamp 
FROM ticket_status as ts
left join ticket_reply as tr on(ts.support_ID=tr.support_ID)
left join ticket as t on(t.support_ID=tr.support_ID)
where status_ID=40
order by status_timestamp desc
limit 1;

答案 2 :(得分:1)

根据给出的示例,它看起来所有时间戳都是等价的,所以像这样的查询就足够了:

SELECT
  ticket.*,
  ticket_reply.*
FROM
  (SELECT   support_ID, MAX(status_timestamp) as max_timestamp
   FROM     ticket_status
   GROUP BY support_ID) m
  INNER JOIN ticket
  ON m.support_ID=ticket.support_ID
     AND m.max_timestamp=ticket.`timestamp`
  INNER JOIN ticket_reply
  ON m.support_ID=ticket_reply.support_ID
     AND m.max_timestamp=ticket_reply.reply_timestamp
  INNER JOIN ticket_status
  ON m.support_ID=ticket_status.support_ID
     AND m.max_timestamp=ticket_status.status_timestamp
WHERE
  status_ID=40;

但是根据应用程序的逻辑,可能会发生表格中的最后一行的时间戳为2014-09-27 09:41:18,而另一行的时间戳为2014-09-27 09:41:19

在这种情况下,您应该使用类似这样的查询:

SELECT
  ticket.*,
  ticket_reply.*
FROM
  (SELECT   support_ID, MAX(status_timestamp) AS max_status_timestamp
   FROM     ticket_status
   GROUP BY support_ID) m_status
  INNER JOIN
  (SELECT   support_ID, MAX(reply_timestamp) AS max_reply_timestamp
   FROM     ticket_reply
   GROUP BY support_ID) m_reply
  ON m_status.support_ID=m_reply.support_ID
  INNER JOIN
  (SELECT   support_ID, MAX(`timestamp`) AS max_ticket_timestamp
   FROM     ticket
   GROUP BY support_ID) m_ticket
  ON m_status.support_ID=m_ticket.support_ID

  INNER JOIN ticket_status
  ON ticket_status.support_ID=m_status.support_ID
     AND ticket_status.status_timestamp=m_status.max_status_timestamp

  INNER JOIN ticket_reply
  ON ticket_reply.support_ID=m_reply.support_ID
     AND ticket_reply.reply_timestamp=m_reply.max_reply_timestamp

  INNER JOIN ticket
  ON ticket.support_ID=m_ticket.support_ID
     AND ticket.`timestamp`=m_ticket.max_ticket_timestamp
WHERE
  ticket_status.status_ID=40;

请参阅小提琴here