SQLServer2005面试题:GROUP BY与子查询应用解析

需积分: 3 22 下载量 131 浏览量 更新于2024-10-16 收藏 29KB DOC 举报
"SQLServer 2005面试题,主要涉及GROUP BY子句和条件计数" 在SQL Server 2005中,面试题经常涉及到如何有效地处理数据分组和统计。以下是一个典型的面试题,目的是计算每天的胜利(胜)和失败(负)次数: 题目描述: 给定一个表`#tmp`,包含两个字段:`rq`(日期)和`shengfu`(胜负)。表中的数据表示每天的比赛结果,'胜'代表胜利,'负'代表失败。面试题要求编写SQL语句,输出每天的日期以及对应的胜利次数和失败次数,格式如下: ``` 日期 胜 负 2005-05-09 2 2 2005-05-10 1 2 ``` 解答方法: 方法一: 可以使用嵌套的子查询来实现这个需求。首先,对于每个日期,分别计算胜利和失败的次数: ```sql SELECT s1.rq AS '日期', (SELECT COUNT(shengfu) FROM [tiku].[dbo].[uuu] AS s2 WHERE shengfu = '胜' AND s1.rq = s2.rq) AS '胜', (SELECT COUNT(shengfu) FROM [tiku].[dbo].[uuu] AS s3 WHERE shengfu = '负' AND s1.rq = s3.rq) AS '负' FROM [tiku].[dbo].[uuu] AS s1 GROUP BY s1.rq ``` 这个查询通过内嵌的子查询分别计算每个日期的胜利和失败次数,然后在外部查询中按日期进行分组。 方法二: 使用CASE语句结合SUM函数,也可以达到同样的效果: ```sql SELECT rq AS '日期', SUM(CASE WHEN shengfu = '胜' THEN 1 ELSE 0 END) AS '胜', SUM(CASE WHEN shengfu = '负' THEN 1 ELSE 0 END) AS '负' FROM #tmp GROUP BY rq ``` 这里,我们利用了CASE语句将胜负转换成数字(胜利为1,失败为0),然后使用SUM函数对每个日期的胜利和失败次数求和。 方法三: 还可以通过两次聚合操作,分别计算胜利和失败的次数,然后通过JOIN合并结果: ```sql WITH N AS ( SELECT rq, 勝 = COUNT(*) FROM #tmp WHERE shengfu = '胜' GROUP BY rq ), M AS ( SELECT rq, 負 = COUNT(*) FROM #tmp WHERE shengfu = '负' GROUP BY rq ) SELECT N.rq, N.勝, M.負 FROM N INNER JOIN M ON N.rq = M.rq ``` 这个方法首先用CTE(公共表表达式)创建两个临时表,分别存储胜利和失败的次数,然后通过JOIN操作将两者合并。 这些方法都可以正确地解决面试题中的问题,但在实际生产环境中,根据数据量和性能要求,可能需要权衡不同的解决方案。例如,对于大数据集,使用CASE语句和SUM函数可能会更高效,因为它只需要一次扫描表;而对于小数据集,嵌套的子查询或JOIN操作可能更为简洁直观。在面试时,理解各种方法的优缺点,并能根据实际情况选择最佳方案,是展示SQL技能的关键。