sql - 为什么 CROSS APPLY 与列和聚合函数需要 Group by
问题描述
问题
为什么在 SELECT 上混合使用列和聚合函数的 CROSS APPLY 查询不起作用?它需要 GROUP BY 子句或具有聚合函数的所有列。
代码
CREATE TABLE A
(
A_ID int identity(1,1),
A_NAME Varchar(20)
)
INSERT INTO A (A_NAME)
VALUES
('A'), ('AA'), ('AAA')
CREATE TABLE B
(
B_ID int identity(10,10),
B_NAME Varchar(20),
A_ID int
)
INSERT INTO B (B_NAME, A_ID)
VALUES
('B', 1), ('BB', 3), ('BBB', 2)
--如果选择的列与聚合函数混合,则不起作用
SELECT A_NAME, MAX(B_NAME)
FROM A
CROSS APPLY(SELECT * FROM B WHERE B.A_ID = A.A_ID) as AxB
--使用聚合函数
SELECT MAX(A_NAME), MAX(B_NAME)
FROM A
CROSS APPLY(SELECT * FROM B WHERE B.A_ID = A.A_ID) as AxB
--与 GROUP BY 一起工作
SELECT A_NAME, MAX(B_NAME)
FROM A
CROSS APPLY(SELECT * FROM B WHERE B.A_ID = A.A_ID) as AxB
GROUP BY A_NAME
- 重启
DROP TABLE A
DROP TABLE B
更新
结论(感谢@Richardissimo)
我有 Sybase 15.7 背景,您可以将列与聚合函数混合在一起,并且没有 Group by Clause。在这些情况下,默认组将是整个表。所以在我的代码中,我期待 A 表中所有 A_NAMES 的最大 B_NAME。
但是,在 SQL Server 中,当我测试没有交叉应用的代码时,我收到了同样的错误。它看起来像 SQL Server 禁止这种类型的行为。这有点酷,他们说你不会得到比聚合查询上的组数更多的行。
这是一致性
解决方案
该问题与 无关cross apply
,它与聚合的工作方式有关。让我们回顾一下您的 3 个场景:
SELECT A_NAME, MAX(B_NAME)
withGroup By A_NAME
意味着您会为每个不同的 A_NAME 返回一行,并且每个都将伴随着 B_NAME 的“最大”值,其中 A_NAME 具有该值。
SELECT MAX(A_NAME), MAX(B_NAME)
没有分组依据,这意味着分组是在所有行中完成的,这意味着查询只会返回一行。
SELECT A_NAME, MAX(B_NAME)
没有Group By
没有意义。如果它只是SELECT A_NAME
,它将为每一行返回 A_NAME 中的值。因此MAX(B_NAME)
,输入相同的查询是没有意义的,因为没有 aGroup By
它就无法知道要聚合什么。
希望这可以帮助。
推荐阅读
- docker - 如何在不启动容器的情况下从 dockerfile 创建图像
- javascript - 如何获取从本地文件获取的元数据?
- python - 无法从插件文件夹导入创建的包
- javascript - 使用 AJAX 和控制器通过下拉选择填充索引页面
- curl - 带有 CURL OAuth 的 Google Search Console API
- angular6 - Angular 6 本地设置
- fetch - fetch 从哪里获取它的端点值?
- google-apps-script - 如何将提示数据作为变量传递到 google docs 绑定脚本中?
- linux - Postfix——如何安全存储Mysql配置
- reactjs - 如何根据使用反应的条件返回 jsx?