mysql中group by 用别名的疑问

圣殿骑士18 2018-08-14 12:06:05
最近在检查一个mysql问题的时候,发现mysql查询结果不对是因为在group by 中使用了别名。
然后我百度了一下,也了解了在group by 中不能用别名的原因,下图可以解释:

但我仍然有其他疑问,想问一下专家:
1、为什么在group by中如果使用别名,不会报错?不报错是个很大的坑,有些问题几个月都没有发现
2、我分别有两个案例,都是在group by中使用别名,一个案例数据能够正确查询。另外一个案例,不能正确查询。
两者查询结果不同的案例:
SELECT		#语句1:正规
gc.Column11 AS Season,
g.GoodsName AS Category,
gc.Column3 AS Buyer
FROM
sam_ba_goods g
INNER JOIN sam_ba_goodscustom gc ON g.GoodsId = gc.GoodsId
INNER JOIN sam_ba_item i ON g.GoodsId = i.GoodsId
WHERE
gc.Column4 IS NOT NULL
AND g.EntId = 1002
and gc.Column11 = '2017_冬'
GROUP BY
gc.Column11,
g.GoodsName,
gc.Column3;

SELECT #语句2:按别名Group By
gc.Column11 AS Season,
g.GoodsName AS Category,
gc.Column3 AS Buyer
FROM
sam_ba_goods g
INNER JOIN sam_ba_goodscustom gc ON g.GoodsId = gc.GoodsId
INNER JOIN sam_ba_item i ON g.GoodsId = i.GoodsId
WHERE
gc.Column4 IS NOT NULL
AND g.EntId = 1002
and gc.Column11 = '2017_冬'
GROUP BY
Season,
Category,
Buyer

一个个5条记录,一个是4条记录:


另外一个案例,两者的查询结果相同,也就是Group By中使用别名仍然查询出了正确的数据:
SELECT		#语句1:按别名Group By
gc.Column11 AS Season,
g.GoodsName AS Category,
gc.Column3 AS Buyer,
gc.Column5 AS Price,
i.ItemId AS ItemId,
i.BorrowedTimes
FROM
sam_ba_goods g
INNER JOIN sam_ba_goodscustom gc ON g.GoodsId = gc.GoodsId
INNER JOIN sam_ba_item i ON g.GoodsId = i.GoodsId
WHERE
gc.Column4 IS NOT NULL
AND g.EntId = 1002
GROUP BY #按别名Group By
Season,
Category,
Buyer,
ItemId
order by Season,
Category,
Buyer,
ItemId;

SELECT #语句2:正规
gc.Column11 AS Season,
g.GoodsName AS Category,
gc.Column3 AS Buyer,
gc.Column5 AS Price,
i.ItemId AS ItemId,
i.BorrowedTimes
FROM
sam_ba_goods g
INNER JOIN sam_ba_goodscustom gc ON g.GoodsId = gc.GoodsId
INNER JOIN sam_ba_item i ON g.GoodsId = i.GoodsId
WHERE
gc.Column4 IS NOT NULL
AND g.EntId = 1002
GROUP BY
gc.Column11,
g.GoodsName,
gc.Column3,
i.ItemId
order by Season,
Category,
Buyer,
ItemId;


第2个问题是,为什么还是在Group By中使用别名,有时候可以查询出正确的数据?这是种什么机制?这个情况迷惑性非常大,因为有时候用别名了,也能出正确数据,会让人误以为可以这么用。

注:为了排除聚合函数可能的影响,在sql中我都剔除了聚合函数。这不是问题。
...全文
542 点赞 收藏 9
写回复
9 条回复
圣殿骑士18 2020年03月27日
引用 8 楼 duandr 的回复:
mysql本身就支持在 group by 中使用别名。请参考 https://blog.csdn.net/nice_hui_/article/details/89391224 。

可能是因为我用的是5.6版本?
回复 点赞
duandr 2020年01月07日
mysql本身就支持在 group by 中使用别名。请参考 https://blog.csdn.net/nice_hui_/article/details/89391224 。
回复 点赞
圣殿骑士18 2018年09月07日
引用 6 楼 ACMAIN_CHM 的回复:
建议贴出一个能够实际反映问题的SQL语句,这样方便分析。

贴的1楼已经列出了4个对比SQL
回复 点赞
圣殿骑士18 2018年09月05日
而且,我的提示不是ambiguous,ambiguous是可疑的,可疑的情况下,还可以在方案中二选一,从而得出一个结果。
我show warnnings提示是You have an error。。。这是错误,为什么错误的情况下,mysql仍然要输出数据?感觉很不严谨了。

基于有限的信息,我只能猜测是:
1、mysql对sql执行前,没有做足够的预检
2、sql执行过程中的解析步骤中,发现的问题,并不会中断mysql的执行,mysql的策略是,尽量的猜测并输出数据,而不是中断执行。这和其他数据库引擎不太相同(我用过sqlserver,sybase,oracle),可能是引擎本身不够强大,如果所有存疑都中断执行,会影响用户体验。
回复 点赞
圣殿骑士18 2018年09月05日
引用 3 楼 zjcxc 的回复:
mysql> select 1 as id from(select 1 as id union all select 2 as id) a group by id;
+----+
| id |
+----+
| 1 |
| 1 |
+----+
2 rows in set, 1 warning (0.00 sec)

mysql> show warnings;
+---------+------+---------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------+
| Warning | 1052 | Column 'id' in group statement is ambiguous |
+---------+------+---------------------------------------------+

这个原因吧,查询的表中有别名同名的列,这个时候会使用表中的列,不会用查询结果别名在对应的列,可能你可以看到警告

你说的基本正确。我使用命令行后,发现了具体的warnning消息。
+----------+------------+-----------+
| Season | Category | Buyer |
+----------+------------+-----------+
| 2017_冬 | 配饰S | 叶铭卉 |
| 2017_冬 | 配饰S | 吴燕群 |
| 2017_冬 | 羽绒服Y | 周鸿 |
| 2017_冬 | 配饰S | 罗云 |
+----------+------------+-----------+
4 rows in set, 1 warning (0.00 sec)

mysql> show warnnings;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'warnn
ings' at line 1


不过这仍然不能解释,为什么另外一个案例里,我也试过了,一样提示warning,show warnnings的提示结果也同样,但却有正确的结果?
回复 点赞
ACMAIN_CHM 2018年09月05日
建议贴出一个能够实际反映问题的SQL语句,这样方便分析。
回复 点赞
学海无涯-回头是岸 2018年08月15日
很多库都不能这么写,要么把前面的带别名的表转成派生表,再group by 别名
回复 点赞
mysql> select 1 as id from(select 1 as id union all select 2 as id) a group by id;
+----+
| id |
+----+
| 1 |
| 1 |
+----+
2 rows in set, 1 warning (0.00 sec)

mysql> show warnings;
+---------+------+---------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------+
| Warning | 1052 | Column 'id' in group statement is ambiguous |
+---------+------+---------------------------------------------+

这个原因吧,查询的表中有别名同名的列,这个时候会使用表中的列,不会用查询结果别名在对应的列,可能你可以看到警告
回复 点赞
发动态
发帖子
MySQL
创建于2007-09-28

2.4w+

社区成员

5.5w+

社区内容

MySQL相关内容讨论专区
社区公告
暂无公告