我的看法与其他人有点不同......我是否遗漏了一些东西,或者除了明显的索引优化之外,您的所有连接都位于查找的主键上 - 您的标准准确吗?
这就是我的意思...你的最后一个 WHERE 子句..
WHERE
r.client_id IN ( SELECT opinion_id
FROM pacra_client_opinion_relations
WHERE client_id = 50 )
Run Code Online (Sandbox Code Playgroud)
您要求 CLIENT_ID 位于 OPINION_ID 的选择结果中,但仅查找 client_ID = 50 的意见。Opinion_id 的上下文是什么。
表“pacra_client_opinion_relations”中客户与意见的澄清让我们看一下示例数据,如下所示
Opinion_ID Client_ID Other...
1 28 ...
2 35 ...
3 50 ...
4 2 ...
5 50 ...
6 6 ...
7 50 ...
8 4 ...
Run Code Online (Sandbox Code Playgroud)
如果您的查询是 client_id = 50 的所有 OPINION_ID,则您将返回 OPINION_ID #s 3、5 和 7。由于您的 where 子句要求在选择意见中提供 CLIENT_ID,因此您现在正在获取客户端 3、5 和 7 的数据与您最初开始关注的客户 #50 无关。
另外...如果您只查找“Client_ID = 50”中的内容,那么您之前的查询试图获取第二个最近的通知日期,那么您正在查询所有客户端。如果您为“Client_ID = 50”添加 where 子句,那么您将只能收到这些通知,而不会收到所有客户端的第二个到最近的通知。
澄清 MAX() 小于内部 MAX()。来自评级的前数据您将得到以下...
og_ratings (assuming this data is pre-sorted per client for sample purposes)
client_id notification_date
13 Sep 5 <- You want THIS entry if it was client 13 included
13 Sep 14 <- Most recent for client 13
28 Sep 1
28 Sep 8
28 Sep 10 <- You want THIS entry if client 28 included
28 Sep 11 <- Most recent for client 28
29 Sep 4 <- You want THIS entry if client 29 included
29 Sep 11 <- Most recent for client 29
43 Sep 16 <- Most recent for client 43 and no prior,
this would never show as only one entry for client
50 Sep 2
50 Sep 9
50 Sep 12 <- You want THIS entry for client 50
50 Sep 15 <- Most recent for client 50
Run Code Online (Sandbox Code Playgroud)
根据样本数据,您会得到...不同的客户可能有与最新日期截然不同的第二个日期
client_id notification_date
13 Sep 5
28 Sep 10
29 Sep 4
50 Sep 12
Run Code Online (Sandbox Code Playgroud)
如果您在 OUTERMOST 查询中只关心客户端 50,而您的实际数据有数百个客户端(甚至数千个客户端),那么您正在查询所有客户端。您可以通过以下方式专门限制您的内部查询:客户端 50
og_ratings r INNER JOIN (
SELECT
client_id,
max(notification_date) notification_2nd_date
FROM
og_ratings
WHERE
(client_id, notification_date)
NOT IN ( SELECT client_id, max(notification_date)
FROM og_ratings
GROUP BY client_id )
GROUP BY
client_id
ORDER BY
client_id DESC
Run Code Online (Sandbox Code Playgroud)
可以调整为...
og_ratings r INNER JOIN (
SELECT
client_id,
max(notification_date) notification_2nd_date
FROM
og_ratings
WHERE
client_id = 50 <--- ADDED TO WHERE CLAUSE for CLIENT 50 ONLY
AND (client_id, notification_date)
NOT IN ( SELECT client_id, max(notification_date)
FROM og_ratings
WHERE client_id = 50 <--- ADDED HERE TOO FOR CLIENT 50
GROUP BY client_id )
GROUP BY
client_id
ORDER BY
client_id DESC
Run Code Online (Sandbox Code Playgroud)
它只会返回客户 50 的单个记录,而不返回所有客户的日期
client_id notification_date
50 Sep 12
Run Code Online (Sandbox Code Playgroud)
最后,在多次提供 MySQL 查询时,我都建议使用关键字 STRAIGHT_JOIN。这基本上告诉MySQL按照你告诉它的顺序进行查询...有时,当(例如你的情况),你有一堆查找表时,它可能会尝试为你考虑并首先使用查找表,因为低它应用查询的记录计数(或什么/无论如何)。
SELECT STRAIGHT_JOIN ...查询的其余部分
如果我的假设准确,也可以进行更简化的查询,我只是想解释我认为有问题的不同部分......最后,当您看到我拥有的示例数据时,如果您可以准备示例关于您所拥有的和您想要获得的当前和未来的数据可能会有所帮助......