为什么此代码能够在 HAVING 中使用来自 SELECT 的别名?
Why is this code able to use an alias from SELECT in HAVING?
我在网上找到这个解决方案 HackerRank problem:
SELECT c.hacker_id, h.name, COUNT(c.challenge_id) AS cnt
FROM Hackers AS h
JOIN Challenges AS c ON h.hacker_id = c.hacker_id
GROUP BY c.hacker_id, h.name
HAVING
cnt = (SELECT COUNT(c1.challenge_id) FROM Challenges AS c1 GROUP BY c1.hacker_id ORDER BY COUNT(*) DESC LIMIT 1) OR
cnt NOT IN (SELECT COUNT(c2.challenge_id) FROM Challenges AS c2 GROUP BY c2.hacker_id HAVING c2.hacker_id <> c.hacker_id)
ORDER BY cnt DESC, c.hacker_id;
可以看到,cnt
定义在SELECT中,然后在HAVING中使用。我的理解是,从逻辑上讲,GROUP BY and HAVING 运行 before SELECT。因此,我希望 SQL 在执行 GROUP BY 时不会识别 cnt
,并抛出错误。但是,代码给出了正确的解决方案。
谁能解释一下为什么?也许 MySQL 人为地纠正了这个问题?
您假设 SELECT
子句中定义的别名不能在 HAVING
子句中使用 通常 正确:这在标准 SQL(也称为 ANSI SQL),大多数数据库不允许这样。
然而,MySQL 扩展了标准,如解释的那样 in the documentation:
The MySQL extension permits the use of an alias in the HAVING
clause for the aggregated column.
所以您显示的代码不是有效的 ANSI SQL,但它是一个有效的 MySQL 查询。 MySQL 实现了对 ANSI SQL 的许多其他扩展,并在链接文档中进行了描述。
更一般地说,据我所知,没有一个数据库是完全严格遵守ANSI规范的。它们都缺少功能和扩展。学习 SQL,您还需要了解您所使用的数据库的特性 运行。
我在网上找到这个解决方案 HackerRank problem:
SELECT c.hacker_id, h.name, COUNT(c.challenge_id) AS cnt
FROM Hackers AS h
JOIN Challenges AS c ON h.hacker_id = c.hacker_id
GROUP BY c.hacker_id, h.name
HAVING
cnt = (SELECT COUNT(c1.challenge_id) FROM Challenges AS c1 GROUP BY c1.hacker_id ORDER BY COUNT(*) DESC LIMIT 1) OR
cnt NOT IN (SELECT COUNT(c2.challenge_id) FROM Challenges AS c2 GROUP BY c2.hacker_id HAVING c2.hacker_id <> c.hacker_id)
ORDER BY cnt DESC, c.hacker_id;
可以看到,cnt
定义在SELECT中,然后在HAVING中使用。我的理解是,从逻辑上讲,GROUP BY and HAVING 运行 before SELECT。因此,我希望 SQL 在执行 GROUP BY 时不会识别 cnt
,并抛出错误。但是,代码给出了正确的解决方案。
谁能解释一下为什么?也许 MySQL 人为地纠正了这个问题?
您假设 SELECT
子句中定义的别名不能在 HAVING
子句中使用 通常 正确:这在标准 SQL(也称为 ANSI SQL),大多数数据库不允许这样。
然而,MySQL 扩展了标准,如解释的那样 in the documentation:
The MySQL extension permits the use of an alias in the
HAVING
clause for the aggregated column.
所以您显示的代码不是有效的 ANSI SQL,但它是一个有效的 MySQL 查询。 MySQL 实现了对 ANSI SQL 的许多其他扩展,并在链接文档中进行了描述。
更一般地说,据我所知,没有一个数据库是完全严格遵守ANSI规范的。它们都缺少功能和扩展。学习 SQL,您还需要了解您所使用的数据库的特性 运行。