GROUP BY DESC如何选择订单?

时间:2016-03-02 12:55:23

标签: mysql

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

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

我的桌子示例:

SELECT * FROM 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?我尝试了几种不同的组合,我很奇怪每次得到我的预期结果,但我不明白为什么。

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

PS

我已尝试更新option_identifier id = 7以查看MySql是否引用了最新保存在磁盘上但未更改结果。

:我不打算使用此功能或要求替代方案,我在问它是怎么回事?

2 个答案:

答案 0 :(得分:2)

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选择什么值? 1723?为什么17以及为什么23

它没有任何标准支持17超过23。它只挑选其中一个(可能是17但这取决于很多内部因素)而且是一个。

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

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

根据标准SQL,您的查询无效且无法执行。但是,一些数据库引擎如上所述运行它。表达式的值不是(至少下面的一个):

是不确定的。

5.7.5版以来,MySQL实施了functional dependency detection,默认情况下,它拒绝了与您无关的GROUP BY查询。

如何使其发挥作用

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

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

答案 1 :(得分:0)

GROUP BY默认按升序对记录进行排序。您的store_id根本没有被引用,而是返回的记录按section_identifier

的升序排序