LeetCode #合作过至少三次的演员和导演

127 阅读2分钟

一、题目

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;
  • 显示结果

image.png

三、执行语句

假表

image.png

having

image.png

四、总结

  • group by: group by 后跟一个或者多个字段,跟一个字段是根据这个字段进行分组,多个的话就是以多个字段进行分组。这里注意是将几个字段放在同一个分组来进行处理的,并不是将多个字段分隔开
  • having: having的存在就是为了弥补where关键字无法与合计函数一起使用,因此在这里使用having也能达到效果
  • count(*): 这里是指返回表中的所有记录包括null,这里和conut(TIMESTAMP)相同,因为TIMESTAMP是主键,但是第一种写法相对方便一些,因此这里用了第一种