mysql - 分组排序

标签 mysql group-by sql-order-by

目前我想了解为什么组中的顺序会发生变化,甚至认为我“给”它正确的“第一”行。

CREATE TABLE IF NOT EXISTS `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `A` int(11) NOT NULL,
  `B` int(11) NOT NULL,
  `C` int(11) NOT NULL,
  `D` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;

INSERT INTO `test` (`id`, `A`, `B`, `C`, `D`) VALUES
(1, 1, 77, 0, 'Vasya'),
(2, 1, 77, 999, 'Masha'),
(6, 1, 77, 999, 'Clone'),
(3, 1, 88, 1, 'Natasha'),
(4, 2, 1, 1, 'Dima'),
(5, 3, 1, 1, 'Katya');

这两个查询给出相同的答案:

SELECT A, B, C, D, id FROM `test` WHERE `A`=1 AND `B`=77 ORDER BY `C` DESC

SELECT DISTINCT A, B, C, D, id FROM `test` WHERE `A`=1 AND `B`=77 ORDER BY `C` DESC

但这两个给出了不同的答案:

SELECT * FROM (
    SELECT A, B, C, D, id FROM `test` WHERE `A`=1 AND `B`=77 ORDER BY `C` DESC
) AS t  GROUP BY A, B


SELECT * FROM (
    SELECT DISTINCT A, B, C, D, id FROM `test` WHERE `A`=1 AND `B`=77 ORDER BY `C` DESC
) AS t  GROUP BY A, B

我只想获取最大为“C”的行,它们属于一个“A”和一个“B”。但是没有'不同'。 我做错了什么?

PS:我必须添加 A=1 才能更加具体。工作项目中没有这样的条件,不是选择一行的查询。

最佳答案

当使用 group by 时,标准做法是将所有非聚合列放在 group by 子句中(或者,如果 MySQL 选项 ONLY_FULL_GROUP_BY 被禁用:所有在功能上不依赖于 group by 子句中已有的其他列的列)。您的查询不符合这条黄金法则:因此您得到的结果不一致。

在 MySQL 8.0 中,您可以使用窗口函数解决此问题:

select id, a, b, c, d
from (
    select 
        t.*,
        row_number() over(partition by a, b order by c desc, id) rn
    from test t
) x
where rn = 1

在早期版本中,相关子查询可以完成工作(在您的用例中,这实际上可能比 row_number() 更有效):

select t.*
from test t
where id = (
    select id 
    from test t1 
    where t1.a = t.a and t1.b = t.b 
    order by c desc, id 
    limit 1
)

在这个 demo on DB Fiddle ,两个查询都返回:

| id  | A   | B   | C   | D       |
| --- | --- | --- | --- | ------- |
| 2   | 1   | 77  | 999 | Masha   |
| 3   | 1   | 88  | 1   | Natasha |
| 4   | 2   | 1   | 1   | Dima    |
| 5   | 3   | 1   | 1   | Katya   |

关于mysql - 分组排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58432635/

相关文章:

mysql - 如何在MYSQL中创建不同类型的ID?

mysql - 使用 Yii2 查询从带有函数的 MySQL 选择返回值

mysql - 对行进行分组并对每个组进行排序

sql - 对连续整数求和并分组

sql - SQL 查询的特殊排序

mysql - Rails - 使用 SQL 查询获取回形针 URL

php - 动态提取用 php 和 ajax 更新的 html 表

php - 按年月归档

mysql - 非常慢的查询曾经非常快。 Explain 在本地备份上显示 rows=1 但在服务器上显示 rows=2287359

php - 如何按 MySQL 中不同表的两个日期字段之间的最新更新日期排序