SQL Server中group by用法以及容易出错的点

本文详细解析SQL Server中GROUP BY子句的使用方法及常见错误,包括如何结合聚合函数进行数据分组统计,以及WHERE与HAVING子句的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SQL Server中,group by 一般是和聚合函数一起搭配使用的,不然用了也没什么意

除了消除重复功能外,但消除重复一般使用distinct

例如,有这样的一学生成绩表(学号,课程号,成绩)


我们按学号分组查询,

select SNo from sc  group by SNo

结果:


     从上面我们可以看到,group by 子句可以将查询结果按某一列或多列的值进行分

组。

容易出错的点:

       (1) 出现在select后面的字段 要么是是聚合函数中的,要么是在group by 中的。

什么意思?

        例如:还是上面那个表,当我执行以下语句:

          select sno,cno from sc group by sno


        报错:(可能mySQL不会,因为它的执行是不严格的)

      

       因为,我的select字段中有cno课程号,但却不是在聚合函数或者group by子句

中,所以报错。

       正确用法:   

//这一句是查看,每个人修读了几门课
select sno,count(cno) from sc group by sno

//这里先按学号分组再按课程号分组,只按学号分组不会出现重复的学号的
select sno,cno from sc group by SNo,CNo
4

  (2) 如果是筛选结果 可以先使用where指定条件 再用group by 或者先用group 

by 再用having来指定条件,(聚合函数不能出现在where子句中,只可以和select  

或having搭配,SQL Server会报错,据说MySQL不会报错)

//查询选修两个门课及以上的学生     

//报错
select SNo from sc  group by SNo where count(*)>1 
//正解
select SNo from sc  group by SNo having count(*)>1 

//查看每个学生选了几门课,且选的课的成绩不为空

//报错,group by要在where后面
select sno,count(cno) from sc group by SNo where score is not null 
//正解
select sno,count(cno) from sc where score is not null  group by SNo

总结

       之前在面试试题看到这样一道题,有一个学生成绩表,就像

我们上面说的那个表一样,查询学生成绩重复的


确认过眼神,以为很简单,上来就是

select Score from sc  group by Score having count(*)>1

and score is not null


毫无疑问,当然是错的,一开始没看到是查询行,也就是查询的

要包括整个元组的信息。想了想改成:


select * from sc  group by Score having count(*)>1  and 

score is not null

也是错的,犯了上面的问题。想了想,无奈,用内连接。

select a1.SNo,a1.CNo,a1.Score from sc a1

inner join sc on  sc.Score=a1.Score and (a1.SNo!=sc.SNo 

or a1.cno !=sc.CNo)

虽然结果对了,但是个人感觉要是做项目这样查,领导和同事得

用刀砍死我,因为耗费资源,效率还慢。


哎,简洁写法

select * from sc where score in(

   select Score from sc  group by Score having count(*)>1  

   and score is not null

)


       这种东西还是得多练,刚上手时更是得练,如果感觉上手了

就搁置一段时间,用到时又得回去翻笔记。写下来,希望和各位

道友共勉。



### SQL Server 查询错误的原因分析与解决方案 #### 一、关于 pymssql.OperationalError: (20009, b'Unknown error') 当使用 Python 的 `pymssql` 库连接到 SQL Server 数据库时,如果遇到 `(20009, b'Unknown error')` 错误,通常是因为网络配置或服务器设置不正确引起的。以下是可能的原因及其对应的解决方案: - **原因 1**: 非默认端口未指定 如果 SQL Server 使用的是非标准端口(不是默认的 1433),而客户端未显式指明该端口号,则可能导致无法建立连接[^1]。 **解决方案**: 明确指定目标 SQL Server 实例的端口号,在连接字符串中加入端口参数。例如: ```python conn = pymssql.connect(server='your_server_name', port=12345, user='username', password='password', database='dbname') ``` - **原因 2**: TCP/IP 协议被禁用 默认情况下,某些安装环境下的 SQL Server 可能会关闭 TCP/IP 支持,这将阻止外部通过 IP 地址访问数据库实例。 **解决方案**: 启用 SQL Server 上的 TCP/IP 协议支持。可以通过以下步骤完成:打开 SQL Server Configuration Manager -> Network Configuration -> Protocols for MSSQLSERVER 或对应命名实例 -> 将 TCP/IP 设置为 Enabled。 - **原因 3**: Windows 防火墙拦截请求 若防火墙上未开放相应的端口(通常是 1433 或自定义端口),则可能会导致连接失败。 **解决方案**: 添加一条入站规则允许特定端口通信。具体操作如下:控制面板 -> 系统和安全 -> Windows Defender 防火墙 -> 高级设置 -> 新建入站规则 -> 端口 -> 输入要使用的端口号。 --- #### 二、多表查询与 GROUP BY 报错问题 在执行涉及多个表格联合查询并应用聚合函数的操作时,“select 字句中的列名必须为分组列或列函数”的报错提示表明当前 SELECT 列表中有不符合条件的内容存在[^2]。这种类型的错误主要源于以下几个方面: - **原因 1**: 不恰当的选择字段组合 当使用了 `GROUP BY` 子句之后,任何出现在最终结果集里的非聚集型数据项都应当成为分组依据的一部分;否则就会违反语法规则引发异常情况发生。 **解决方案**: 修改查询逻辑使得所有非汇总类别的项目均被列入至 group by 中去或者转换成相应形式表达式的计算值。比如下面这个例子展示了如何修正原始版本以满足上述约束条件的要求。 假设原有问题查询如下所示: ```sql SELECT a.id, b.name, COUNT(*) FROM tableA AS a JOIN tableB AS b ON a.bid=b.id WHERE ... GROUP BY a.id; ``` 正确写法应该是这样子的形式之一: ```sql -- 方法 A: 扩展 Group By 范围 SELECT a.id, b.name, COUNT(*) FROM tableA AS a JOIN tableB AS b ON a.bid=b.id WHERE ... GROUP BY a.id, b.name; -- 方法 B: 对额外字段采用 Aggregation Function 进行处理 SELECT a.id, MAX(b.name), COUNT(*) FROM tableA AS a JOIN tableB AS b ON a.bid=b.id WHERE ... GROUP BY a.id; ``` 综上所述,针对不同场景下产生的各类错误现象给出了针对性较强的排查思路以及实际可行的技术手段来加以应对解决这些问题。 ---
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

legendaryhaha

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值