精讲Mysql各种高难度Sql编写(三)

精讲Mysql各种高难度Sql编写(三)

sql 继续更新,前面的六篇,老哥写的马马虎虎,不知道大家消化得怎么样了,如果感觉很难,千万不要气馁,因为人总是需要一个慢慢适应的过程的,多看几次就好了。

  考虑到要写的内容太多了,所以从这篇开始,5个sql查询,同时保证质量。

  接着,继续肝文,

sql1

这题是 Leetcode 数据库 620 题

题目:找出所有影片描述为非 boring (不无聊) 的并且 id 为奇数 的影片,结果请按等级 rating 排列
在这里插入图片描述

输出:
在这里插入图片描述

sql脚本:
DROP TABLE IF EXISTS cinema;
CREATE TABLE cinema (
id int(0) NOT NULL,
movie varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
description varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
rating varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO cinema VALUES (1, ‘War’, ‘great 3D’, ‘8.9’);
INSERT INTO cinema VALUES (2, ‘Science’, ‘fiction’, ‘8.5’);
INSERT INTO cinema VALUES (3, ‘irish’, ‘boring’, ‘6.2’);
INSERT INTO cinema VALUES (4, ‘Ice song’, ‘Fantacy’, ‘8.6’);
INSERT INTO cinema VALUES (5, ‘House card’, ‘Interesting’, ‘9.1’);

解法一、一看这个题的时候,感觉很难,但是做了之后发现好像挺简单的,哈哈哈

select * from cinema where description <> 'boring' and id % 2 =1 ORDER BY rating desc

sql2

这题是 Leetcode 数据库 627 题

题目:交换工资,
有 m = 男性 和 f = 女性 的值。交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然)。要求只使用一个更新(Update)语句,并且没有中间的临时表。

在这里插入图片描述

sql脚本:
DROP TABLE IF EXISTS salary;
CREATE TABLE salary (
id int(0) NOT NULL,
name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
sex varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
salary int(0) NULL DEFAULT NULL,
PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO salary VALUES (1, ‘A’, ‘m’, 2500);
INSERT INTO salary VALUES (2, ‘B’, ‘f’, 1500);
INSERT INTO salary VALUES (3, ‘C’, ‘m’, 5500);
INSERT INTO salary VALUES (4, ‘D’, ‘f’, 500);

解法一、老哥解法,使用 if 函数

update salary set sex = if(sex = 'f', 'm', 'f')

解法二、大神解法,使用case判断,我没想到的是mysql 也可以这么玩

update salary
set sex = case sex
                when 'f' then 'm'
                else  'f'
                end

解法三、官方解法,利用asci码解决问题

update salary set sex = char(ascii('m') + ascii('f') - ascii(sex));

sql3

这题是 Leetcode 数据库 626 题

题目:小美是一所中学的信息科技老师,她有一张 seat 座位表,平时用来储存学生名字和与他们相对应的座位 id。

其中纵列的 id 是连续递增的

小美想改变相邻俩学生的座位。

如果学生人数是奇数,则不需要改变最后一个同学的座位。

在这里插入图片描述

输出:
在这里插入图片描述

sql脚本:
DROP TABLE IF EXISTS seat;
CREATE TABLE seat (
id int(0) NULL DEFAULT NULL,
student varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO seat VALUES (1, ‘Abbot’);
INSERT INTO seat VALUES (2, ‘Doris’);
INSERT INTO seat VALUES (3, ‘Emerson’);
INSERT INTO seat VALUES (4, ‘Green’);
INSERT INTO seat VALUES (5, ‘Jeames’);

解法一、常规解法,老哥参考了一下其他大佬

SELECT (CASE 
            WHEN MOD(id,2) = 1 AND id = (SELECT COUNT(*) FROM seat) THEN id
            WHEN MOD(id,2) = 1 THEN id+1
            ElSE id-1
        END) AS id, student
FROM seat
ORDER BY id;	

解法二、官方解法,先拿到seat总数,然后利用case when 分情况讨论

select (case
      when mod(id,2)!=0 and id!=counts then id+1
      when mod(id,2)!=0 and id=counts then id
      else id-1 end)as id,student
      from seat,(select count(*)as counts from seat)as seat_counts
 order by id;

解法三、大神解法,用与1 异或,将奇数变偶数,偶数变奇数。又用-1对最后一行为奇数行的情况进行处理,只能说牛逼

select rank() over(order by (id-1)^1) as id,student from seat

sql4

这题是 Leetcode 数据库 1179 题

题目: 编写一个 SQL 查询来重新格式化表,使得新的表中有一个部门 id 列和一些对应 每个月 的收入(revenue)列。

说白了,就是竖着放变成横着放
在这里插入图片描述
输出:
在这里插入图片描述
sql脚本:
CREATE TABLE department2(
id INT,
revenue INT,
MONTH VARCHAR(10),
PRIMARY KEY(id, MONTH));

INSERT INTO department2 VALUE(1, 8000, ‘Jan’),(2, 9000, ‘Jan’),(3, 10000, ‘Feb’),(1, 7000, ‘Feb’),(1, 6000, ‘Mar’);

解法一、使用sum聚合函数,然后case分情况讨论,revenue 是该属性字段,then revenue 表示为null

SELECT id,
SUM(CASE `month` WHEN 'Jan' THEN revenue END) Jan_Revenue,
SUM(CASE `month` WHEN 'Feb' THEN revenue END) Feb_Revenue,
SUM(CASE `month` WHEN 'Mar' THEN revenue END) Mar_Revenue
FROM department2
GROUP BY id;

解法二、和上面一样,也是分情况讨论,差不多

SELECT id,
MAX(IF(`month`='Jan',revenue,NULL)) Jan_Revenue,
MAX(IF(`month`='Feb',revenue,NULL)) Feb_Revenue,
MAX(IF(`month`='Mar',revenue,NULL)) Mar_Revenue
FROM Department2
GROUP BY id;

sql5

这是Leetcode 数据库 512题 游戏分析II

题目:这个表显示的是某些游戏玩家的游戏活动情况
每一行是在某天使用某个设备登出之前登录并玩多个游戏(可能为0)的玩家的记录
请编写一个 SQL 查询,描述每一个玩家首次登陆的设备名称

在这里插入图片描述
输出:
在这里插入图片描述
sql脚本:
DROP TABLE IF EXISTS activity;
CREATE TABLE activity (
player_id int(0) NOT NULL,
device_id int(0) NULL DEFAULT NULL,
event_date date NOT NULL,
games_played int(0) NULL DEFAULT NULL,
PRIMARY KEY (player_id, event_date) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO activity VALUES (1, 2, ‘2016-03-01’, 5);
INSERT INTO activity VALUES (1, 2, ‘2016-05-02’, 6);
INSERT INTO activity VALUES (2, 3, ‘2017-06-25’, 1);
INSERT INTO activity VALUES (3, 1, ‘2016-03-02’, 0);
INSERT INTO activity VALUES (3, 4, ‘2018-07-03’, 5);

解法一、老哥写的,先拿到玩家id,最早时间,然后in两个,作条件过滤

select player_id,device_id from activity where (player_id,event_date) in(
select player_id,min(event_date) as late from activity GROUP BY player_id
)

解法二、内连接,和上面差不多

select a.player_id,a.device_id from activity a join 
(select player_id,min(event_date) as late from activity GROUP BY player_id)
b
on (a.player_id=b.player_id and a.event_date =b.late)

解法三、大佬写法,先对日期排序,拿到最早日期,然后子查询,秒秒秒!

SELECT 
  player_id,
  device_id 
FROM
  activity AS A 
WHERE event_date = 
  (SELECT 
    event_date 
  FROM
    activity 
  WHERE player_id = A.`player_id` 
  ORDER BY event_date 
  LIMIT 1) ;
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jesscia ^_^

您的打赏将是我努力的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值