[英]Changing ORDER BY caluse with LIMIT in MySQL SELECT gives inconsistent set of rows
我很惊讶今天从以下MySQL查询中发现不一致的结果:
SELECT Research.Focus, Research.Media, Country.Name, GROUP_CONCAT(DISTINCT AskMethod.Name ORDER BY ResearchAskMethod.MethodID SEPARATOR ', ') as AskMethodName, Research.ResearchDate, Research.ResearchID FROM AskMethod INNER JOIN ((Country INNER JOIN Research ON Country.CountryID = Research.CountryID) INNER JOIN ResearchAskMethod ON Research.ResearchID = ResearchAskMethod.ResearchID) ON AskMethod.MethodID = ResearchAskMethod.MethodID WHERE Research.ResearchID=ResearchAskMethod.ResearchID AND Research.ResearchDate=1996 GROUP BY Research.ResearchID ORDER BY Country.Name, Research.Media, AskMethodName, Research.ResearchDate DESC LIMIT 0, 5;
该查询给了我5行: ResearchID
:18、17、10、7、13。
如果我只是将DESC
添加到第一个ORDER BY
参数,则它变为:
...ORDER BY Country.Name DESC, Research.Media...
,
该查询为我提供了不同的5行集: ResearchID
:8、14、9、13、7
ResearchID
是Research
表的主键。
如果我只是更改ORDER BY
参数的顺序,它也会给我一个不同的集合,例如:
... ORDER BY Research.Media, Country.Name, AskMethodName...
您能帮我了解发生了什么吗?
下面由@Kiley回答,这是固定查询:
SELECT *
FROM (
SELECT Research.Focus, Research.Media, Country.Name, GROUP_CONCAT( DISTINCT ValMethod.Name
ORDER BY ResearchValMethod.MethodID
SEPARATOR ', ' ) AS ValMethodName, Research.ResearchDate, Research.ResearchID
FROM ValMethod
INNER JOIN (
(
Country
INNER JOIN Research ON Country.CountryID = Research.CountryID
)
INNER JOIN ResearchValMethod ON Research.ResearchID = ResearchValMethod.ResearchID
) ON ValMethod.MethodID = ResearchValMethod.MethodID
WHERE Research.ResearchID = ResearchValMethod.ResearchID
AND Research.ResearchDate = 1996
GROUP BY Research.ResearchID
ORDER BY Country.Name, Research.Media, ValMethodName, Research.ResearchDate
) AS Result
ORDER BY Result.Name, Result.Media, ValMethodName, Result.ResearchDate DESC
我认为这里的问题是,您希望按ResearchDate的顺序排列前五个结果,然后再按降序对THOSE进行排序。 根据PinalDave的说法 , SELECT TOP X
子句(与LIMIT
的功能的子集等效)在SELECT
查询的逻辑处理中是FINAL步骤,因此在对结果进行ORDER
运算后,它将获取第一个X
。
如果您对处理顺序感到好奇,可以在《 MySQL参考手册》上找到:
HAVING子句几乎是最后一次应用,即将项目发送到客户端之前,没有进行优化。 (HAVING之后应用限制。)
这是一个简单的示例,将演示我认为您遇到的问题以及解决方法:
CREATE TABLE [Test] (
Number INT PRIMARY KEY
);
INSERT INTO [Test] VALUES (1);
INSERT INTO [Test] VALUES (2);
INSERT INTO [Test] VALUES (3);
INSERT INTO [Test] VALUES (4);
INSERT INTO [Test] VALUES (5);
INSERT INTO [Test] VALUES (6);
INSERT INTO [Test] VALUES (7);
INSERT INTO [Test] VALUES (8);
INSERT INTO [Test] VALUES (9);
INSERT INTO [Test] VALUES (10);
这样就可以设置您的数据了。 现在运行以下查询并检查输出:
SELECT TOP 5 * FROM Test ORDER BY Number;
在MySQL中:
SELECT * FROM Test ORDER BY Number LIMIT 5;
该查询将产生以下结果集:
1
2
3
4
5
现在,在这里查看区别:
SELECT TOP 5 * FROM Test ORDER BY Number DESC;
在MySQL中:
SELECT * FROM Test ORDER BY Number DESC LIMIT 5;
产生:
10
9
8
7
6
注意结果集不同吗? 这就是您现在遇到的问题。 相反,您需要做的是在子查询中选择所需的结果,然后在外部查询中对THOSE进行排序。
SELECT * FROM (
SELECT TOP 5 * FROM Test ORDER BY Number
) AS MyTest ORDER BY Number DESC
最后,在MySQL中:
SELECT * FROM (
SELECT * FROM Test ORDER BY Number LIMIT 5
) AS MyTest ORDER BY Number DESC
结果?
5
4
3
2
1
我想这就是您要寻找的。
我不是MySQL专家,但我还发现了LIMIT的一些巧妙功能,可让您指定返回结果集的上限和下限,因此,如果您确切知道表中预期有多少行(您可能不知道t,但我认为这可能值得您理解),您可能会这样(仅MySQL示例:)
SELECT * FROM Test ORDER BY Number DESC LIMIT 6, 10
我将按照下面提供的示例来固定您的查询,但是由于它的格式有些欠妥,因此很难判断到底发生了什么……:
SELECT * FROM (SELECT Research.Focus, Research.Media, Country.Name, GROUP_CONCAT(DISTINCT AskMethod.Name ORDER BY ResearchAskMethod.MethodID SEPARATOR ', ') as AskMethodName, Research.ResearchDate, Research.ResearchID FROM AskMethod INNER JOIN ((Country INNER JOIN Research ON Country.CountryID = Research.CountryID) INNER JOIN ResearchAskMethod ON Research.ResearchID = ResearchAskMethod.ResearchID) ON AskMethod.MethodID = ResearchAskMethod.MethodID WHERE Research.ResearchID=ResearchAskMethod.ResearchID AND Research.ResearchDate=1996 GROUP BY Research.ResearchID ORDER BY Country.Name, Research.Media, AskMethodName, Research.ResearchDate) AS Result ORDER BY Country.Name, Research.Media, AskMethodName, Research.ResearchDate DESC
;
作为记录,我建议稍微清理一下查询的布局,以使它们更易于理解。 就像在PHP或C#或Java或C ++或任何其他编程语言中一样,使用换行符,空白间距等来提高代码的可读性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.