SQL练习——LeetCode解题和总结(2)
602. Friend Requests II: Who Has the Most Friends[M]
一、表信息
In social network like Facebook or Twitter, people send friend requests and accept others' requests as well.
table:request_accepted
二、题目信息
找出拥有好友数最多的用户编号及其拥有的好友数。所有的请求默认都被处理了。
注意:
- 只有一个用户拥有最多的好友数
- 好友邀请只能被接受一次,因此要去除重复值
For the sample data above, the result is:
三、参考SQL
1 WITH t1 AS ( SELECT DISTINCT requester_id, accepter_id FROM request_accepted597 ), 2 t2 AS ( SELECT requester_id AS id FROM t1 ), 3 t3 AS ( SELECT accepter_id AS id FROM t1 ) 4 5 SELECT * 6 FROM 7 ( SELECT 8 id, 9 count( * ) AS num 10 FROM( SELECT id FROM t2 UNION ALL SELECT id FROM t3 ) temp 11 GROUP BY id 12 ) t 13 ORDER BY num DESC 14 LIMIT 1;
思路:
(你加别人或者别人加你,你都多了一个好友。所以无论你的ID是出现在requester_id还是accepter_id,都证明你多了一个好友)
1、t1用于去重。因为两个相同用户之间发送多次请求和接受,都只能算是同一个好友。(生活中的场景:以前初中用QQ的时候,暗恋同班一个女童鞋,要到了她的QQ,周一到周五晚上一放学就去网吧打毒奶粉,顺便加女神的QQ,但是女神没有回应,于是周一到周五每天都加了一次,谁知道女神是好同学,只有周五回家才上网,她周五回到家了把我周一到周五发送的所有请求加好友消息都同意了,我瞬间有了五个女朋友,嘻嘻。。。)
2、去重之后,用t2和t3分别把请求和相应的ID都提取出来,在union all把他们拼接在一起,得到temp表
3、此时问题就转化为id出现次数最多的问题了。分组——统计个数——倒序——截取第一个最大值即可
(PS:这里默认自己不能加自己为好友,也就是requester_id不等于accepter_id。记得以前QQ可以给自己发好友请求的。假若最多好友数不止一个人,或者求好友数前三的信息。就和前面的一些题目很李类似)
方法二:网友答案
1 SELECT c.people as id, SUM(c.cnt) AS num 2 FROM ( 3 SELECT requester_id AS people, COUNT(DISTINCT accepter_id) AS cnt 4 FROM request_accepted 5 GROUP BY requester_id 6 7 UNION ALL 8 9 SELECT accepter_id AS people, COUNT(DISTINCT requester_id) AS cnt 10 FROM request_accepted 11 GROUP BY accepter_id 12 ) AS c 13 14 GROUP BY c.people 15 ORDER BY SUM(c.cnt) DESC 16 LIMIT 1;
思路:
1、子查询1:自己主动加了几个人
2、子查询2:有几个人主动加了我
3、把两个子查询拼接起来,就是我一共有几个好友
(PS:思路差不多,这两个子查询用的很妙,但是前提还是自己不能加自己为好友。注意union all 和 union distinct的区别!)
603. Consecutive Available Seats[E]
一、表信息
cinema表为某电影院选座情况,包含座位编号以及座位是否可选。
Several friends at a cinema ticket office would like to reserve consecutive available seats.
二、题目信息
找出连续座位的编号。
Can you help to query all the consecutive available seats order by the seat_id using the following cinema table?
注意:
- 座位编号是自动递增的整数型数据,是否可选是一个逻辑值 (1代表可选,0代表不可选)
- 连续座位可选指至少连续的两个座位是可以选的
Note:
- The seat_id is an auto increment int, and free is bool ('1' means free, and '0' means occupied.).
- Consecutive available seats are more than 2(inclusive) seats consecutively available.
Your query should return the following result for the sample case above.
三、参考SQL
方法一:
1 SELECT 2 seat_id 3 FROM 4 ( 5 SELECT c1.seat_id AS seat_id 6 FROM cinema603 c1 7 INNER JOIN cinema603 c2 8 ON c1.free = c2.free AND c1.seat_id = c2.seat_id - 1 9 ) t1 10 UNION 11 ( 12 SELECT c2.seat_id AS seat_id 13 FROM cinema603 c1 14 INNER JOIN cinema603 c2 15 ON c1.free = c2.free AND c1.seat_id = c2.seat_id - 1 16 ) 17 ;
思路:
1、因为ID是自增的。连接条件,让下一个的free值等于上一个的free值,那么这两个座位就是可以连坐的。
2、在把两列拼接起来去重即可
方法二:官方答案
1 SELECT DISTINCT a.seat_id 2 FROM cinema603 AS a JOIN cinema603 AS b 3 ON ABS(a.seat_id - b.seat_id) = 1 4 AND a.free = TRUE AND b.free = TRUE 5 ORDER BY a.seat_id;
加绝对值,可以让表的id相差为1的记录连接两次。但是假若题目要求至少连续三个为1就不能这么写了。
607. Sales Person[E]
一、表信息
这题太简单
二、题目信息
三、参考SQL
608. Tree Node[M]