我的托管将mysql版本从5.6改为5.7(禁用了only_full_group_by),我的查询出现问题。
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
在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中GROUP BY不采用第一个元素,而是随机的?
答案 0 :(得分:2)
使用不带聚合函数的GROUP BY
任意选择值。 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;
答案 1 :(得分:1)
您只是观察MySQL文档一直说的内容:select
查询的group by
中的非聚合列来自不确定行。你不应该使用这种语法。这是一个MySQL(mis)功能,它只会导致比它解决的问题更多的问题,并且它在任何其他非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');
这可以利用test(number, lang)
上的索引来获得最佳效果。
答案 2 :(得分:0)
如果它们在mysql 5.7中的GROUP BY之前站在子查询中,似乎所有ORDER BY都将被忽略。
我的查询中有同样的问题。我找到了解决方法。您可以按键列添加“ORDER 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`
答案 3 :(得分:0)
您可以在子查询中使用limit
来使order by
工作:
SELECT
*
FROM
(
SELECT
`id`,
`category`,
`name`,
`number`,
`lang`
FROM
`test`
WHERE
`category` = 'Cat1'
ORDER BY
FIELD(lang, 'EN', 'JP')
LIMIT 999999999
) 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