Нужно объединить 3 таблицы.Нужно заказать по полю DateTime и ограничить 1 - PullRequest
0 голосов
/ 20 апреля 2019

У меня есть эти таблицы:

CUSTOMERS

Customer ID | Customer Name
----------------------------
1000        | Jonny Ltd.
1001        | James Ltd.
TICKETS

Ticket ID | Ticket Customer | Ticket Subject
---------------------------------------------
10         | 1000            | Testing Sub
11         | 1001            | Testing Sub 2 
12         | 1001            | Testing Sub 3 
Notes

Note ID | Note Ticket ID | Note Content   | Note Created
---------------------------------------------------------------
1       | 10             | Testing Note1. | 2019-04-20 13:38:16
2       | 10             | Testing Note2. | 2019-04-20 12:52:36
3       | 11             | Testing Note3. | 2019-04-19 10:21:54

Я хочу показать каждый билет, упорядоченный по их последней заметке.Когда я запускаю эту команду, она не дает правильного ответа.

SELECT `Ticket ID`,`Customer Name`, `Ticket Subject`, `Note Content`, `Note Created`
FROM TICKETS t, CUSTOMERS c, NOTES n
WHERE t.`Ticket Customer` = c.ID AND n.`Note Ticket ID` = t.`Ticket ID`
ORDER BY n.`Note Created` DESC;

Я хочу вывести:

Ticket ID  | Company Name | Ticket Subject | Note Content   | Note Created
---------------------------------------------------------------------------
10         | Jonny Ltd.   | Testing Sub    | Testing Note1. | 2019-04-20 13:38:16
11         | James Ltd.   | Testing Sub 2  | Testing Note3. | 2019-04-19 10:21:54
12         | James Ltd.   | Testing Sub 3  | NULL           | NULL

Ответы [ 3 ]

2 голосов
/ 20 апреля 2019

Вам нужен подзапрос, чтобы определить самую последнюю заметку для каждого тикета. Эта версия помещает подзапрос в предложение ON:

SELECT `Ticket ID`, `Customer Name`, `Ticket Subject`, `Note Content`, `Note Created`
FROM TICKETS t JOIN
     CUSTOMERS c
     ON t.`Ticket Customer` = c.ID LEFT JOIN
     NOTES n
     ON n.`Note Ticket ID` = t.`Ticket ID` AND
        n.`Note Created` = (SELECT MAX(n2.`Note Created`)
                            FROM NOTES n2
                            WHERE n2.`Note Ticket ID` = t.`Ticket ID`
                           )
ORDER BY (n.`Note Created` IS NOT NULL) DESC,
         n.`Note Created` DESC;

Примечания:

  • Никогда не используйте запятые в предложении FROM. Всегда используйте правильный, явный, стандартный JOIN синтаксис.
  • Используйте LEFT JOIN, чтобы получить билеты без заметок.
  • Я бы рекомендовал переименовать столбцы, чтобы они не включали пробелы. Отсутствие экранирующих идентификаторов облегчит написание запросов.
  • ORDER BY должен гарантировать, что значения NULL являются последними. DESC ставит значения NULL последними, но на всякий случай я добавил явную логику для этого.

В MySQL 8+ вы бы вместо этого использовали оконные функции:

SELECT `Ticket ID`, `Customer Name`, `Ticket Subject`, `Note Content`, `Note Created`
FROM TICKETS t JOIN
     CUSTOMERS c
     ON t.`Ticket Customer` = c.ID LEFT JOIN
     (SELECT n.*,
             ROW_NUMBER() OVER (PARTITION BY n.`Note Ticket ID` ORDER BY n.`Note Created` DESC) as seqnum
      FROM NOTES n
     ) n
     ON n.`Note Ticket ID` = t.`Ticket ID` AND
        n.seqnum = 1
ORDER BY (n.`Note Created` IS NOT NULL) DESC,
         n.`Note Created` DESC;
2 голосов
/ 20 апреля 2019

Чтобы получить последние данные заметок, вам нужно определить самую последнюю дату заметки для каждого билета. Вы можете сделать это с помощью этого запроса:

SELECT `Note Ticket ID`, MAX(`Note Created`) AS `Note Created`
FROM Notes
GROUP BY `Note Ticket ID`

Затем можно использовать этот запрос в качестве производной таблицы, чтобы выбрать все данные из последней заметки, а JOIN - в таблицу Customers и Tickets:

SELECT t.`Ticket ID`, c.`Customer Name`, t.`Ticket Subject`,
       n.`Note Content`, n.`Note Created`
FROM Customers c
LEFT JOIN Tickets t ON t.`Ticket Customer` = c.`Customer ID`
LEFT JOIN (SELECT `Note Ticket ID`, MAX(`Note Created`) AS `Note Created`
           FROM Notes
           GROUP BY `Note Ticket ID`) nc ON nc.`Note Ticket ID` = t.`Ticket ID`
LEFT JOIN Notes n ON n.`Note Ticket ID` = nc.`Note Ticket ID` AND
                     n.`Note Created` = nc.`Note Created`
ORDER BY n.`Note Created` DESC

Выход:

Ticket ID   Ticket Subject  Customer Name   Note Content    Note Created
10          Testing Sub     Jonny Ltd.      Testing Note1.  2019-04-20 13:38:16
11          Testing Sub 2   James Ltd.      Testing Note3.  2019-04-19 10:21:54
12          Testing Sub 3   James Ltd.      null            null

Демонстрация по dbfiddle

1 голос
/ 20 апреля 2019

Одним из способов является использование подзапросов, которые получают верхний ряд заметок, когда они упорядочены по времени создания по убыванию или по максимальному времени создания соответственно.

SELECT t.`Ticket ID`,
       c.`Customer Name`,
       t.`Ticket Subject`,
       (SELECT n.`Note Content`
               FROM notes n
               WHERE n.`Note Ticket ID` = t.`Ticket ID`
               ORDER BY n.`Note Created` DESC
               LIMIT 1) `Note Content`,
       (SELECT max(n.`Note Created`)
               FROM notes n
               WHERE n.`Note Ticket ID` = t.`Ticket ID`) `Note Created`
       FROM tickets t,
            LEFT JOIN customers c
                      ON c.`Customer ID` = t.`Ticket Customer`;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...