所以我正在为商店创建部分。商店可以有多个范围,如果没有为给定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是否引用了最新保存在磁盘上但未更改结果。
:我不打算使用此功能或要求替代方案,我在问它是怎么回事?
答案 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
选择什么值? 17
或23
?为什么17
以及为什么23
?
它没有任何标准支持17
超过23
。它只挑选其中一个(可能是17
但这取决于很多内部因素)而且是一个。
确定section_identifier
的值没有问题。它是用于GROUP BY
的列,其在组中的所有值都相等。
选择困境再次出现在option_identifier
和store_id
列上。
根据标准SQL
,您的查询无效且无法执行。但是,一些数据库引擎如上所述运行它。表达式的值不是(至少下面的一个):
GROUP BY
子句; SELECT
条款中的GROUP BY
aggregate functions一起使用; GROUP BY
子句中使用的列; 是不确定的。
自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
的升序排序