SQL笔试题(2)
1.在SQL中语法规范中,having子句的使用下面描述正确的是:( )
A、having子句即可包含聚合函数作用的字段也可包括普通的标量字段
B、使用having的同时不能使用where子句
C、having子句必须于group by 子句同时使用,不能单独使用
D、使用having子句的作用是限定分组条件
E、Having子句和where子句是等同的
F、如果select语句中没有聚合函数的使用,就不能使用having子句
答案:AC
解析:
having是在分组后过滤,where在分组前过滤,不冲突,可以同时使用,BE错;
having是用来过滤的,group by是限定分组,D错;
select语句中没有聚合函数的使用时也可以用having,F错
一、HAVING 的作用
✅
HAVING用于筛选GROUP BY分组后的结果集。
WHERE:在分组前过滤原始行(不能用聚合函数);HAVING:在分组后过滤分组(可以用COUNT()、SUM()、AVG()等聚合函数)。
二、基本语法结构
SELECT 列, 聚合函数(...)
FROM 表
[WHERE 条件] -- 可选:过滤原始数据
GROUP BY 列 -- 按某列分组
HAVING 聚合条件; -- 必须配合 GROUP BY 使用
⚠️
HAVING必须与GROUP BY一起使用(除非是某些数据库的特殊扩展,但标准 SQL 要求如此)。
三、举个例子 🌰
假设有一个订单表 orders:
| order_id | customer_id | amount |
|---|---|---|
| 1 | 101 | 200 |
| 2 | 101 | 300 |
| 3 | 102 | 150 |
| 4 | 103 | 500 |
需求:找出总消费金额超过 400 的客户
❌ 错误写法(用 WHERE):
-- 报错!WHERE 不能直接用聚合函数
SELECT customer_id, SUM(amount)
FROM orders
WHERE SUM(amount) > 400 -- ❌ 不合法
GROUP BY customer_id;
✅ 正确写法(用 HAVING):
SELECT customer_id, SUM(amount) AS total
FROM orders
GROUP BY customer_id
HAVING SUM(amount) > 400;
2.在一个事务中,先后执行以下操作:1. SELECT 库存 FROM 商品 WHERE id=101(结果10);2. UPDATE 商品 SET 库存=9 WHERE id=101;3. COMMIT。此时另一个并发事务在步骤1后立即查询同一商品库存,READ COMMITTED 隔离级别下会返回什么?
A、立即返回9
B、等待第一个事务提交后返回10
C、等待第一个事务提交后返回9
D、立即返回10
答案:D
解析:
在READ COMMITTED隔离级别下,事务只能读取已提交的数据。另一个并发事务在第一个事务的步骤1(SELECT)后立即查询时,第一个事务的UPDATE操作尚未提交(因为UPDATE在步骤2,且未执行COMMIT),因此另一个事务会立即返回查询时已提交的值,即库存10。选项A错误,因为未提交的更新(库存9)不可见;选项B和C错误,因为在READ COMMITTED下SELECT查询不会等待写事务提交,不会出现等待行为;选项D正确,符合隔离级别规则。
3.下列选项中关于数据库事务的特性描述正确的是()
A、事务允许继续分割
B、多个事务在执行事务前后对同一个数据读取的结果是不同的
C、一个事务对数据库中数据的改变是暂时的
D、并发访问数据库时,各并发事务之间数据库是独立
答案:D
解析:此题考查数据库事务的原子性、一致性、隔离性和持久性。A选项,事务是最小的执行单位,不允许分割;B选项,执行事务前后,数据保持一致,对同一数据读取的结果相同;C选项,一个事务被提交后对数据库中数据的改变是持久的。
