聚合函数和GROUP BY的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聚合函数和GROUP BY的问题相关的知识,希望对你有一定的参考价值。

一个表有id,name,sex,class等字段。
SELECT count(*) AS num,id,name,sex,class
FROM table
where name LIKE '%a%'
GROUP BY id
ORDER BY id DESC

会出错,将GROUP BY id 改成GROUP BY id,name,sex,class可成功,但查出来的count(*)不符合我期望的值,比如说表中有a,ab,abc.应该查出count(*)为3,但这样只为1。求高手指点。另如果分2次查,存储过程怎么写?

参考技术A select a.id,a.name,a.sex,a.class,b.num from table a,
(select id,count(*) as num from table
where name LIKE '%a%'
GROUP BY id) b
where a.id=b.id
order by a.id desc本回答被提问者采纳
参考技术B select a.id,a.name,a.sex,a.class,b.num from table a,
(select id,count(*) as num from table
where name LIKE '%a%'
GROUP BY id) b
where a.id=b.id
order by a.id desc.
聚合函数对一组值执行计算并返回单一的值。聚合函数忽略空值。聚合函数经常与 SELECT 语句的 GROUP BY 子句一同使用。
参考技术C select T.num,A.* from table A,(SELECT id,count(*) AS num from table where where name LIKE '%a%' group by id) B where A.id=B.id order by id desc

为啥 CROSS APPLY 与列和聚合函数需要 Group by

【中文标题】为啥 CROSS APPLY 与列和聚合函数需要 Group by【英文标题】:Why CROSS APPLY with columns and aggregate functions needs Group by为什么 CROSS APPLY 与列和聚合函数需要 Group by 【发布时间】: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)) 是我在代码部分编辑的错字。感谢您的贡献:) 【参考方案1】:

这个问题与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 它就无法知道要聚合什么。

希望这会有所帮助。

【讨论】:

嗨@Richardissimo,感谢您的帮助。我在 Sybase 15.7 中编写了很多代码,你可以这样做。基本上,如果您不按默认组放置一个组,则默认组将是整个表。所以在我的代码中,我希望 MAX(B_NAME) 会返回 B 表中的 Max B_Name。我实际上在没有交叉应用的情况下测试了代码并收到了同样的错误。 Looks Like SQL Server 禁止此类行为。这有点酷,他们说你不会得到比实际创建的组数更多的行。这是一致性

以上是关于聚合函数和GROUP BY的问题的主要内容,如果未能解决你的问题,请参考以下文章

为啥 CROSS APPLY 与列和聚合函数需要 Group by

GROUP BY 和聚合函数的参数的适当术语,例如 SUM()

SQL中只要用到聚合函数就一定要用到group by 吗?

聚合函数需要 GROUP BY 吗?

GROUP BY 子句必须与聚合函数一起使用?

可以这样去理解group by和聚合函数