【发布时间】:2018-11-04 19:41:05
【问题描述】:
问题
为什么在 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 包含与聚合函数混合的列,则不起作用
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 禁止这种类型的行为。这有点酷,他们说你不会得到比聚合查询中的组数更多的行。
这是一致的
【问题讨论】:
-
要回答这个问题,我们需要看看您所期望的结果。同样从您的代码中,您可以使用内部连接而不是交叉应用。 max(max(b_name) 也不起作用 - 只有一个 max()。
-
同意 Dale,我假设您试图将 like 与 like 进行比较,但第二个和第三个示例有一个额外的
MAX(。 -
我 @DaleBurrell 你是对的,我应该使用 Inner Join 但我只是想测试交叉应用,我想出了这个例子。双 Max(Max(x)) 是我在代码部分编辑的错字。感谢您的贡献:)
标签: sql sql-server cross-apply