问题
为什么在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's
)我具有Sybase 15.7的背景,您可以在其中混合具有聚合功能的列,并且没有“分组依据”子句。在这种情况下,默认组将是整个表。因此在我的代码中,我期望A表中所有A_NAMES的最大B_NAME。
但是,在SQL Server中,当我测试没有交叉应用的代码时,我收到了相同的错误。看起来SQL Server禁止这种行为。这样做很酷,他们说在汇总查询中,您获得的行数不会超过组数。
这就是一致性
答案 0 :(得分:3)
该问题与cross apply
无关,它与聚合的工作方式有关。让我们回顾一下您的3种情况:
SELECT A_NAME, MAX(B_NAME)
与Group 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)
放在同一个查询中是没有意义的,因为如果没有Group By
,它就无法知道要汇总的内容。
希望这会有所帮助。