简体   繁体   中英

MySQL select values from Multiple Tables dependent on latest value in one

I have the following three tables to look after support tickets in a small web application, but I need some help getting the data I need.

Table 1 (ticket):

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

Table 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

Table 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

The 1st table holds the key ticket information, the 2nd, any replies made to the corresponding ticket, and the third tracks the change in status (statuses are held in another table, but don't need anything from there).

What I need to do is get the number of tickets where the latest status is == 40, and if this is greater than 0, get the latest reply along with the data from the first table.

I've tried multiple ways of doing this, but I am stuck. Don't really want to paste them here as they will likely confuse people, and I doubt they are even close.

This one was rather tricky, however here is a working solution for you.

This query will get the most recent support_reply value for all tickets where the most recent status_ID is 40.

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

You can try this one:

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;

From the example given, it looks that all timestamp are equivalent, so a query like this should be enough:

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;

but depending on the logic of your application, it might happen that the last row in a table has a timestamp of 2014-09-27 09:41:18 and the last in another has for example 2014-09-27 09:41:19 .

In this case, you should use a query like this one:

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;

Please see fiddle here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM