这些练习使用人工构造的数据与接口返回,检查数据库统计、时间解释、工具状态和证据论证中容易遗漏的条件。表名、枚举值、任务编号均为教学约定,不能直接套用于真实应用。SQL 示例通过公共表表达式构造临时查询数据,可以在支持相应语法的 SQLite 环境中运行,不需要创建或修改检材数据库。
解题时应记录答案及其依据。遇到材料不足的题目,需要指出缺少哪项信息、现有材料能够支持什么;猜出一个看似合理的数值不计为完成分析。下文同时给出参考解答,适合自学,也可以由培训者先隐藏解析进行测试。
数据库查询
1. 关注关系有几条,频道有几个
某教学数据库保存了下列记录。follow_state = 1 表示当前关注,0 表示当前未关注;channel_id 是频道标识。
| account_id |
channel_id |
follow_state |
| X |
C01 |
1 |
| X |
C01 |
1 |
| X |
C02 |
1 |
| X |
C03 |
0 |
| Y |
C04 |
1 |
请分别回答:账号 X 有多少条当前关注记录?当前关注多少个不同频道?两份答案能否采用同一个计数表达式?
参考解答: 当前关注记录有 3 条,不同频道有 2 个。账号条件排除 Y,状态条件排除 C03;剩余的两条 C01 记录只对应一个频道。查询如下:
WITH follows(account_id, channel_id, follow_state) AS (
VALUES ('X', 'C01', 1),
('X', 'C01', 1),
('X', 'C02', 1),
('X', 'C03', 0),
('Y', 'C04', 1)
)
SELECT COUNT(*) AS relation_rows,
COUNT(DISTINCT channel_id) AS channels
FROM follows
WHERE account_id = 'X'
AND follow_state = 1;
这道题检查计量对象的选择。若只记下“数量题必须去重”,第一问就会出错。真实检材中还应确认重复行的成因、状态字段的含义,以及频道标识是否为空;这些条件在本题中已明确给定。
2. 一次连接为什么得到三行
消息表有 m1、m2 两条消息。附件表有 a1、a2 两条记录,均属于 m1;m2 没有附件。执行以下查询,三个输出值分别是多少?哪一列能够回答“消息总数”?
WITH messages(msg_id) AS (
VALUES ('m1'), ('m2')
), attachments(attachment_id, msg_id) AS (
VALUES ('a1', 'm1'), ('a2', 'm1')
)
SELECT COUNT(*) AS joined_rows,
COUNT(DISTINCT m.msg_id) AS message_count,
COUNT(a.attachment_id) AS attachment_count
FROM messages AS m
LEFT JOIN attachments AS a ON a.msg_id = m.msg_id;
参考解答: 输出为 3、2、2。连接结果包括 (m1,a1)、(m1,a2) 和 (m2,NULL)。COUNT(*) 计算连接后的行数;不同消息标识有两个;附件标识中的 NULL 不参与 `COUNT(a.attachment_id)