mysql - GROUP BY DESC 如何选择顺序?

标签 mysql

所以我正在为一家商店创建部分。商店可以有多个范围,如果没有为给定的 store_id 设置 section_identifier,它应该回退到全局商店 0 .

我想要的 SQL 命令应该返回任何相关给定商店的 section_options 列表。

我的表格示例:

从 my_table 中选择*:

+----+--------------------+----------------------+----------+
| id | section_identifier | option_identifier    | store_id |
+----+--------------------+----------------------+----------+
| 17 | header             | header_option_one    |        1 |
| 18 | footer             | footer_option_one    |        0 |
| 19 | homepage_feature   | homepage_feature_one |        0 |
| 23 | header             | header_option_three  |        0 |
| 25 | homepage_feature   | homepage_feature_one |        1 |
+----+--------------------+----------------------+----------+

因此 section_identifier 是唯一的,我需要为商店 1 返回的 ID 为 17、18 和 25。

当我运行时:

SELECT * FROM my_table GROUP BY section_identifier 它返回:

+----+--------------------+----------------------+----------+
| id | section_identifier | option_identifier    | store_id |
+----+--------------------+----------------------+----------+
| 18 | footer             | footer_option_one    |        0 |
| 23 | header             | header_option_three  |        0 |
| 19 | homepage_feature   | homepage_feature_one |        0 |
+----+--------------------+----------------------+----------+

这意味着如果我运行SELECT * FROM my_table GROUP BY section_identifier DESC:

我得到了响应(这是我想要的输出):

+----+--------------------+----------------------+----------+
| id | section_identifier | option_identifier    | store_id |
+----+--------------------+----------------------+----------+
| 25 | homepage_feature   | homepage_feature_one |        1 |
| 17 | header             | header_option_one    |        1 |
| 18 | footer             | footer_option_one    |        0 |
+----+--------------------+----------------------+----------+

虽然这有效,但我不明白为什么。

据我所知,最初的GROUP BY应该获得数据库中的第一个实例,IE我期望的响应应该是:

+----+--------------------+----------------------+----------+
| id | section_identifier | option_identifier    | store_id |
+----+--------------------+----------------------+----------+
| 18 | footer             | footer_option_one    |        0 |
| 17 | header             | header_option_three  |        1 |
| 19 | homepage_feature   | homepage_feature_one |        0 |
+----+--------------------+----------------------+----------+

但是,它似乎以某种方式引用了我的 store_id ?我尝试了几种不同的组合,每次都奇怪地得到我预期的结果,但我不明白为什么。

有人可以向我解释一下吗?

附注

我尝试更新 id = 7option_identifier 以查看 MySql 是否引用磁盘上保存的最新内容,但结果没有改变。

另外:我不打算使用此功能或寻求替代方案,我只是想问它是怎么回事?

最佳答案

SELECT * FROM my_table GROUP BY section_identifier

是无效的 SQL 查询。

GROUP BY 如何工作?

让我们获取上面的查询并看看GROUP BY 是如何工作的。首先,数据库引擎选择与 WHERE 子句匹配的所有行。此查询中没有 WHERE 子句;这意味着表的所有行都用于生成结果集。

然后,它使用 GROUP BY 子句中指定的表达式对行进行分组:

+----+--------------------+----------------------+----------+
| id | section_identifier | option_identifier    | store_id |
+----+--------------------+----------------------+----------+
| 17 | header             | header_option_one    |        1 |
| 23 | header             | header_option_three  |        0 |
+----+--------------------+----------------------+----------+
| 18 | footer             | footer_option_one    |        0 |
+----+--------------------+----------------------+----------+
| 19 | homepage_feature   | homepage_feature_one |        0 |
| 25 | homepage_feature   | homepage_feature_one |        1 |
+----+--------------------+----------------------+----------+

我在上面的列表中标记了组,以使一切变得清晰。

下一步,数据库引擎从每个组中生成一行。但如何呢?

查询的 SELECT 子句是 SELECT ** 代表表格列的完整列表;在本例中,SELECT * 是一种简短的写法:

SELECT id, section_identifier, option_identifier, store_id

让我们分析第一组的 id 列的值。数据库引擎应该为 id 选择什么值? 17还是23?为什么是17,为什么是23

它没有任何标准来支持 17 而不是 23。它只是选择其中之一(可能是 17 但这取决于很多内部因素)并选择其中之一。

确定 section_identifier 的值没有问题。它是用于GROUP BY的列,组中的所有值都相等。

option_identifierstore_id 列上再次出现选择困境。


根据标准SQL,您的查询无效且无法执行。但是,某些数据库引擎按上述方式运行它。不存在的表达式的值(至少是以下之一):

  • 用在GROUP BY子句中;
  • GROUP BY aggregate functions 一起使用在 SELECT 子句中;
  • 功能上依赖于 GROUP BY 子句中使用的列;

不确定。

自版本 5.7.5 起,MySQL 实现 functional dependency detection并且默认情况下,它会拒绝像您这样的无效 GROUP BY 查询。

如何让它发挥作用

我不清楚你想如何获得结果集。无论如何,如果您想从表中获取一些行,那么GROUP BY 不是正确的方法。 GROUP BY 从表中选择行,它使用表中的值生成新值。大多数情况下,GROUP BY 生成的行与源表中的任何行都不匹配。

您可以在 this answer 中找到问题的可能解决方案。在阅读并理解这个想法之后,您必须自己编写查询(并且您非常清楚应该如何选择“获胜”行)。

关于mysql - GROUP BY DESC 如何选择顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35747846/

相关文章:

php - 我需要一个包含 2 个动态值的查询

mysql AUTO_INCREMENT 在表上 INSERT....SELECT 之后跳过有效的数字范围

mysql - 为什么在 Laravel 5.8 中创建外键失败?

MySQL 错误 : "1030 - Got error -1 from storage engine"

mysql - 选择并显示表中具有相同值的行数

mysql - select inside insert 语句和过程

php/mysql 将行加在一起得到总数

PYTHON MYSQL 第二次不起作用

mysql - 在mysql中使用root帐户截断多个数据库中的同一个表

java - 如何使用从主机到 docker mysql 服务器的 JDBC 连接