一、题目
ActorDirector 表:
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| actor_id | int |
| director_id | int |
| timestamp | int |
+-------------+---------+
timestamp 是这张表的主键.
写一条SQL查询语句获取合作过至少三次的演员和导演的 id 对 (actor_id, director_id)
示例:
ActorDirector 表:
+-------------+-------------+-------------+
| actor_id | director_id | timestamp |
+-------------+-------------+-------------+
| 1 | 1 | 0 |
| 1 | 1 | 1 |
| 1 | 1 | 2 |
| 1 | 2 | 3 |
| 1 | 2 | 4 |
| 2 | 1 | 5 |
| 2 | 1 | 6 |
+-------------+-------------+-------------+
Result 表:
+-------------+-------------+
| actor_id | director_id |
+-------------+-------------+
| 1 | 1 |
+-------------+-------------+
唯一的 id 对是 (1, 1),他们恰好合作了 3 次。
二、解题思路
创建数据表
根据题意创建数据表,这只字段类型并填充数据
CREATE TABLE IF NOT EXISTS ActorDirector (
actor_id INT,
director_id INT,
TIMESTAMP INT PRIMARY KEY
);
INSERT INTO ActorDirector VALUES
(1, 1, 0),
(1, 1, 1),
(1, 1, 2),
(1, 2, 3),
(1, 2, 4),
(2, 1, 5),
(2, 1, 6);
解题
- 根据题意可知要找合作三次及以上的演员和导演,这里就可以使用分组来处理,使用
group by actor_id, director_id - 这时要计算多次合作的演员和导演的数量,使用count计算,可以使用count(TIMESTAMP),也可以使用
count(*),这时得到了所有演员和导演的合作记录 - 进一步操作,这里可以做区分,第一种是将之前得到的数据集作为假表,进行二次查询,这里查询
count(*)大于等于3的数据集,第二种是通过having进一步的做判断,不过这里的处理数据也是count(*)值大于等于3的情况, - 最后执行语句得到结果
SELECT
actor_id,
director_id
FROM (
SELECT
actor_id,
director_id,
count(*) ct
FROM ActorDirector
GROUP BY actor_id, director_id
HAVING ct >= 3;
) t
SELECT actor_id, director_id
FROM ActorDirector
GROUP BY actor_id, director_id
HAVING COUNT(*) >= 3;
- 显示结果
三、执行语句
假表
having
四、总结
- group by: group by 后跟一个或者多个字段,跟一个字段是根据这个字段进行分组,多个的话就是以多个字段进行分组。这里注意是将几个字段放在同一个分组来进行处理的,并不是将多个字段分隔开
- having: having的存在就是为了弥补where关键字无法与合计函数一起使用,因此在这里使用having也能达到效果
- count(*): 这里是指返回表中的所有记录包括null,这里和conut(TIMESTAMP)相同,因为TIMESTAMP是主键,但是第一种写法相对方便一些,因此这里用了第一种