1

我有以下 SQL 查询,它查询我的票、ticketThreads、用户和 threadStatus 表:

SELECT tickets.threadId, ticketThreads.threadSubject, tickets.ticketCreatedDate,  ticketThreads.threadCreatedDate, threadStatus.threadStatus, users.name
FROM 
tickets 
INNER JOIN 
ticketThreads
ON
tickets.threadId = ticketThreads.threadId
INNER JOIN
threadStatus 
ON
ticketThreads.threadStatus = threadStatus.id
INNER JOIN
users
ON
users.id = ticketThreads.threadUserId
WHERE
tickets.ticketId = ticketThreads.lastMessage
AND 
ticketThreads.threadStatus != 3
ORDER BY
tickets.ticketCreatedDate
DESC

这返回的精简版是:

threadId | 
----------
1        |
2        |

这工作正常,是我所期望的,但是为了稍微清理代码和数据库,我需要删除 ticketThreads.lastMessage 列。

如果我删除该行WHERE tickets.ticketId = ticketThreads.lastMessage,那么这是返回内容的精简版本:

threadId | 
----------
1        |
2        |
1        |

然后我需要做的是编辑上面的查询,使我能够为门票数据库中的每个 threadId 值选择最高的唯一值。

我知道MAX()GROUP BY不知道如何将它们放入我上面的查询中。

表格的相关部分如下所示:

门票

ticketId | ticketUserId | threadId 
-------------------------------
1        | 1            | 1
2        | 1            | 2
3        | 1            | 1

票线程

threadId | lastMessage  | threadStatus
-------------------------------
1        | 3            | 4
2        | 2            | 1

我希望以上所有内容都清楚且有意义

4

1 回答 1

3

所以你需要ticket每个线程具有最高 id 的?您的问题实际上是每组问题的最大记录的非常简单的变体。不需要任何子查询。基本上你有两个选项,它们都应该比你的查询执行得更好,第二个更快(请在你的数据库中发布实际持续时间!):

1. 符合标准的查询,但速度较慢:

SELECT t1.threadId, ticketThreads.threadSubject, t1.ticketCreatedDate,  
    ticketThreads.threadCreatedDate, threadStatus.threadStatus, users.name
FROM tickets as t1
LEFT JOIN tickets as t2 
    ON t1.threadId = t2.threadId AND t1.ticketId < t2.ticketId
JOIN ticketThreads ON t1.threadId = ticketThreads.threadId
JOIN threadStatus ON ticketThreads.threadStatus = threadStatus.id
JOIN users ON users.id = ticketThreads.threadUserId
WHERE t2.threadId is NULL
    AND ticketThreads.threadStatus != 3
ORDER BY t1.ticketCreatedDate DESC

这个加入tickets表两次,这对于大表来说可能会慢一些。

2. 更快,但使用 MySQL 对标准 SQL 的扩展:

set @prev_thread := NULL;

SELECT t.threadId, ticketThreads.threadSubject, t.ticketCreatedDate,  
    ticketThreads.threadCreatedDate, threadStatus.threadStatus, users.name
FROM tickets as t
JOIN ticketThreads ON t.threadId = ticketThreads.threadId
JOIN threadStatus ON ticketThreads.threadStatus = threadStatus.id
JOIN users ON users.id = ticketThreads.threadUserId
WHERE ticketThreads.threadStatus != 3
    AND IF(IFNULL(@prev_thread, -1) = @prev_thread := t.threadId, 0, 1)
ORDER BY t.threadId, t.ticketId DESC,
    t.ticketCreatedDate DESC

在这里,我们对有序连接数据执行一次扫描,使用辅助 mysql 变量@prev_thread仅过滤每个线程的第一个(按给定顺序)票证(具有最高票证 ID 的票证)。

于 2013-07-17T19:02:28.277 回答