分组依据和Mysql 5.7-分组错误
我的主机将mysql版本从5.6改为5.7,只禁用了完整组,我的查询有问题分组依据和Mysql 5.7-分组错误,mysql,Mysql,我的主机将mysql版本从5.6改为5.7,只禁用了完整组,我的查询有问题 SELECT `id`, `category`, `name`, `number`, `lang` FROM `test` WHERE `category` = 'Cat1' ORDER BY FIELD(lang, 'EN', 'JP') 这显示了如下良好结果: 1 Cat1 Test1 23 EN 2 Cat1 Test2 21 EN 2 Cat1 Test1 23 JP 4 Cat1 Test1 23 JP 5
SELECT `id`, `category`, `name`, `number`, `lang`
FROM `test`
WHERE `category` = 'Cat1'
ORDER BY FIELD(lang, 'EN', 'JP')
这显示了如下良好结果:
1 Cat1 Test1 23 EN
2 Cat1 Test2 21 EN
2 Cat1 Test1 23 JP
4 Cat1 Test1 23 JP
5 Cat1 Test2 21 JP
SELECT *
FROM
(
SELECT `id`, `category`, `name`, `number`, `lang`
FROM `test`
WHERE `category` = 'Cat1'
ORDER BY FIELD(lang, 'EN', 'JP')
) as table
GROUP BY number
ORDER BY number DESC
然后我对结果进行分组,只得到一个结果,如下所示:
1 Cat1 Test1 23 EN
2 Cat1 Test2 21 EN
2 Cat1 Test1 23 JP
4 Cat1 Test1 23 JP
5 Cat1 Test2 21 JP
SELECT *
FROM
(
SELECT `id`, `category`, `name`, `number`, `lang`
FROM `test`
WHERE `category` = 'Cat1'
ORDER BY FIELD(lang, 'EN', 'JP')
) as table
GROUP BY number
ORDER BY number DESC
在mysql 5.6中,它起作用了。在5.7中没有
第5.6节的结果:
1 Cat1 Test2 21 EN
2 Cat1 Test1 23 EN
第5.7节的结果:
1 Cat1 Test2 21 JP
2 Cat1 Test1 23 EN
为什么在mysql 5.7中,GROUPBY不取第一个元素,而是随机取一个呢?使用GROUPBY而不使用聚合函数可以任意选取值。MySQL不能保证这一点
SELECT
T.*
FROM
`test` T
INNER JOIN
(
SELECT
MIN(`id`) min_id,
`category`,
`number`
FROM `test`
WHERE `category` = 'Cat1'
GROUP BY `number`
) as t
ON T.`id` = t.min_id AND T.category = t.category AND t.`number` = T.`number`
ORDER BY T.number DESC;
编辑:
为了使Cat1类别下的每个数字都有一行,且lang='EN'为最高优先级:
SELECT
*
FROM
(
SELECT
*,
IF(@sameNumber = `number`, @rn := @rn + 1 ,
IF(@sameNumber := `number`, @rn := 1, @rn := 1)
) AS groupWiseRankNumber
FROM test
CROSS JOIN (SELECT @sameNumber := NULL , @rn := 1) var
WHERE category = 'Cat1'
ORDER BY `number` , FIELD(lang, 'EN','JP')
) AS t
WHERE t.groupWiseRankNumber <= 1;
您只是在观察MySQL文档一直以来所说的:GROUPBYQUERY的select中的非聚合列来自不确定的行。无论如何,您不应该使用此语法。这是一个MySQL的错误特性,它只会导致比它解决的问题更多的问题,并且在任何其他非MySQL派生的数据库中都不可用 以下是一种更有效的方法:
select t.*
from test t
where number = 21 and lang = 'EN'
union all
select t.*
from test t
where number = 21 and lang = 'JP' and
not exists (select 1 from test t2 where t2.number = t.number and t2.lang = 'EN');
这可以利用testnumber、lang上的索引获得最佳性能。在mysql 5.7中,如果所有ORDER BY都位于GROUP BY之前的子查询中,那么它们似乎都将被忽略 我的问题也一样。我找到了工作。您可以按键列添加订单。如果id是表中的主键,则可以添加
GROUP BY `id`
以前
ORDER BY FIELD(lang, 'EN', 'JP')
查询:
`SELECT *
FROM
(
SELECT `id`, `category`, `name`, `number`, `lang`
FROM `test`
WHERE `category` = 'Cat1'
GROUP BY `id`
ORDER BY FIELD(lang, 'EN', 'JP')
) as table
GROUP BY number
ORDER BY number DESC`
您可以使用子查询中的“限制”按工时进行排序:
或者使用GROUP_CONCAT来执行此操作:
SELECT
`id`,
`category`,
`name`,
`number`,
SUBSTRING_INDEX(
GROUP_CONCAT(
lang
ORDER BY
FIELD(lang, 'EN', 'JP')
),
',',
1
) AS lang
FROM
`test`
WHERE
`category` = 'Cat1'
GROUP BY
number
ORDER BY
number DESC
OP的示例数据返回三行,而不是一行。但后面的查询要求结果集中有一行。lang排序在哪里请检查“编辑”部分下的查询,好吗@它总是采用随机元素。这正好是你的第一个案子。这是一种行为。一般来说,在没有任何聚合函数的情况下,不应通过GROUP BY子句在子查询中添加限制1000000。在MariaDB优化了子查询中的ORDERBY子句之后,这对MariaDB起到了作用。但我不能说它是否适用于MySQL 5.7。然而,这只是一个快速修复。您应该重写所有这些查询。解决这个问题还有很多其他方法。而且大多数都更快。