SQL中case when子句的使用(連續變數的區間分段統計場景)
某院系2018年計劃舉辦為期一週的學生電競通關能力預測比賽。現已進入決賽,有6位選手入圍。要求根據給定的兩張表如下所示:
UserUser表(
user_id int,—使用者ID
user_name varchar(50),—使用者姓名
user_type int—使用者型別
)
Game_detail表(
day_id date,—玩遊戲的日期
user_id int,—使用者ID
game_id int,—遊戲ID
duration int—玩遊戲的時長(單位:秒)
)
要求:使用一條SQL語句更新該使用者表(UserUser表)的user_type欄位。在遊戲表中(Game_detail表)累計玩過3-6(包含3和6)個不同遊戲的使用者更新為1,玩過6個以上不同遊戲的更新為2,玩過小於3個遊戲或者沒有玩過遊戲的使用者更新為0.
- sqlite3實現
1.1.code
import sqlite3 as lite with lite.connect('E:/C盤jupyter程式碼備份/Kaggle_in/SQLite/rain.forecast.sqlite') as conn: curs=conn.cursor() #出現database is locked異常,先關閉spyder,重啟Spyder後分次序執行一下三個curs.execute(),每次只能執行一個 curs.execute("""drop table if exists UserUser;""") curs.execute("create table UserUser(user_id int,user_name varchar(25),user_type int)") #curs.execute("""drop TABLE Game_detail""") curs.execute("""drop table if exists Game_detail;""") curs.execute("""CREATE TABLE Game_detail(day_id date,user_id int,game_id int,duration int)""") curs.execute("""insert into UserUser values(100001,'彭彭',0)""") curs.execute("""insert into UserUser values(100002,'玉玉',0)""") curs.execute("""insert into UserUser values(100003,'小青',0)""") curs.execute("""insert into UserUser values(100004,'健健',0)""") curs.execute("""insert into UserUser values(100005,'靜靜',0)""") curs.execute("""insert into UserUser values(100006,'龍龍',0)""") #插入遊戲玩耍記錄表 curs.execute("""insert into Game_detail values('2018-10-20 9:20:15',100001,1012,100)""") curs.execute("""insert into Game_detail values('2018-10-20 9:20:15',100002,101,100)""") curs.execute("""insert into Game_detail values('2018-10-20 9:20:15',100003,101,90)""") curs.execute("""insert into Game_detail values('2018-1-20 9:20:15',100004,1012,60)""") curs.execute("""insert into Game_detail values('2018-3-20 9:20:15',100005,1012,170)""") curs.execute("""insert into Game_detail values('2018-7-20 9:20:15',100006,101,80)""") curs.execute("""insert into Game_detail values('2018-10-20 9:20:15',100006,1013,150)""") curs.execute("""insert into Game_detail values('2018-9-20 9:20:15',100006,1013,100)""") curs.execute("""insert into Game_detail values('2018-2-20 9:20:15',100004,1013,100)""") curs.execute("""insert into Game_detail values('2018-3-20 9:20:15',100004,1013,100)""") curs.execute("""insert into Game_detail values('2018-2-20 9:20:15',100004,1013,40)""") curs.execute("""insert into Game_detail values('2018-2-20 9:20:15',100004,1013,50)""") curs.execute("""insert into Game_detail values('2018-2-20 9:20:15',100002,1016,60)""") curs.execute("""insert into Game_detail values('2018-3-20 9:20:15',100002,1016,90)""") curs.execute("""insert into Game_detail values('2018-2-20 9:20:15',100002,1016,100)""") curs.execute("""insert into Game_detail values('2018-2-20 9:20:15',100002,1016,180)""") curs.execute("""insert into Game_detail values('2018-2-20 9:20:15',100003,1016,130)""") curs.execute("""insert into Game_detail values('2018-2-20 9:20:15',100003,1016,200)""") curs.execute("""insert into Game_detail values('2018-2-20 9:20:15',100003,1016,30)""") curs.execute("""insert into Game_detail values('2018-3-20 9:20:15',100003,1016,110)""") curs.execute("""insert into Game_detail values('2018-2-20 9:20:15',100003,108,120)""") curs.execute("""insert into Game_detail values('2018-2-20 9:20:15',100003,108,80)""") curs.execute("""insert into Game_detail values('2018-2-20 9:20:15',100006,102,90)""") curs.execute("""insert into Game_detail values('2018-5-20 9:20:15',100006,102,90)""") curs.execute("""insert into Game_detail values('2018-5-20 9:20:15',100006,102,40)""") curs.execute("""insert into Game_detail values('2018-5-20 9:20:15',100006,102,50)""") curs.execute("""insert into Game_detail values('2018-6-20 9:20:15',100006,102,60)""") curs.execute("""insert into Game_detail values('2018-7-20 9:20:15',100005,102,120)""") curs.execute("""insert into Game_detail values('2018-8-20 9:20:15',100004,102,150)""") curs.execute("""insert into Game_detail values('2018-7-20 9:20:15',100004,102,160)""") curs.execute("""insert into Game_detail values('2018-8-20 9:20:15',100004,102,190)""") curs.execute("""insert into Game_detail values('2018-7-20 9:20:15',100003,102,180)""") curs.execute("""insert into Game_detail values('2018-8-20 9:20:15',100003,102,170)""") curs.execute("""insert into Game_detail values('2018-8-20 9:20:15',100003,102,110)""") curs.execute("""insert into Game_detail values('2018-7-20 9:20:15',100004,102,120)""") curs.execute("""insert into Game_detail values('2018-7-20 9:20:15',100004,102,130)""") curs.execute("""insert into Game_detail values('2018-12-20 9:20:15',100005,102,140)""") curs.execute("""insert into Game_detail values('2018-12-20 9:20:15',100006,102,170)""") curs.execute("""insert into Game_detail values('2018-12-20 9:20:15',100006,102,190)""") curs.execute("""insert into Game_detail values('2018-7-20 9:20:15',100006,108,20)""") curs.execute("""insert into Game_detail values('2018-11-20 9:20:15',100006,108,130)""") curs.execute("""insert into Game_detail values('2018-11-20 9:20:15',100006,101,190)""") curs.execute("""insert into Game_detail values('2018-7-20 9:20:15',100004,101,120)""") curs.execute("""insert into Game_detail values('2018-7-20 9:20:15',100004,100,130)""") curs.execute("""insert into Game_detail values('2018-12-20 9:20:15',100005,102,140)""") curs.execute("""insert into Game_detail values('2018-12-20 9:20:15',100006,104,170)""") curs.execute("""insert into Game_detail values('2018-12-20 9:20:15',100006,101,190)""") curs.execute("""insert into Game_detail values('2018-7-20 9:20:15',100006,119,20)""") curs.execute("""insert into Game_detail values('2018-11-20 9:20:15',100006,1111,130)""") curs.execute("""insert into Game_detail values('2018-11-20 9:20:15',100006,1111,190)""") curs.execute("""insert into Game_detail values('2018-10-20 9:20:15',100006,101,320)""") curs.execute("""insert into Game_detail values('2018-10-20 9:20:15',100006,102,320)""") curs.execute("""insert into Game_detail values('2018-10-20 9:20:15',100006,103,320)""") curs.execute("""insert into Game_detail values('2018-10-20 9:20:15',100006,108,320)""") curs.execute("""insert into Game_detail values('2018-10-20 9:20:15',100006,1016,320)""") curs.execute("""insert into Game_detail values('2018-10-20 9:20:15',100006,1013,320)""") curs.execute("""insert into Game_detail values('2018-10-20 9:20:15',100006,1020,320)""") curs.execute("""insert into Game_detail values('2018-10-20 9:20:15',100006,1012,320)""") curs.execute("""insert into Game_detail values('2018-10-20 9:20:15',100006,1018,320)""") #curs.execute("select * from (SELECT user_id,count(game_id) FROM Game_detail group by user_id) as A") #curs.execute("select * from UserUser as A left join (SELECT user_id,count(game_id) FROM Game_detail group by user_id) as B on A.user_id=B.user_id") #不考慮遊戲編號去重的條件下: curs.execute("select A.user_id,user_name,user_type,count from UserUser as A left join (SELECT user_id,count(game_id) as count FROM Game_detail group by user_id) as B on A.user_id=B.user_id") data=curs.fetchall() #先查詢所有: curs.execute("select * FROM Game_detail") data=curs.fetchall() #考慮遊戲去重的條件下: curs.execute("select user_id, count(distinct game_id) ct \ from Game_detail \ group by user_id") data=curs.fetchall() #更新資料:注意sqlite3中update後的UserUser表不能使用連線操作獲得的表物件,無法正常執行通過;mysql卻可以。 curs.execute("update UserUser set user_type =(\ select case when ct > 6 then 2\ when ct < 3 then 0\ else 1 end \ from (select user_id, count(distinct game_id) ct from Game_detail group by user_id ) as g \ where UserUser.user_id=g.user_id)") curs.execute("select * from UserUser") data=curs.fetchall()
1.2.效果
1.2.1.UserUser:
1 (100001, ‘彭彭’, 0)
2 (100002, ‘玉玉’, 0)
3 (100003, ‘小青’, 0)
4 (100004, ‘健健’, 0)
5 (100005, ‘靜靜’, 0)
6 (100006, ‘龍龍’, 0)
1.2.2.Game_detail:
0 (‘2018-10-20 9:20:15’, 100001, 1012, 100)
1 (‘2018-10-20 9:20:15’, 100002, 101, 100)
……
56 (‘2018-10-20 9:20:15’, 100006, 1020, 320)
57 (‘2018-10-20 9:20:15’, 100006, 1012, 320)
58 (‘2018-10-20 9:20:15’, 100006, 1018, 320)
1.2.3.使用左連線的實現效果
0 (100001, ‘彭彭’, 0, 1)
1 (100002, ‘玉玉’, 0, 2)
2 (100003, ‘小青’, 1, 4)
3 (100004, ‘健健’, 1, 5)
4 (100005, ‘靜靜’, 0, 2)
5 (100006, ‘龍龍’, 2, 12)
1.2.4.不使用連線的快速寫法(case when 子句實現
0 (100001, ‘彭彭’, 0)
1 (100002, ‘玉玉’, 0)
2 (100003, ‘小青’, 1)
3 (100004, ‘健健’, 1)
4 (100005, ‘靜靜’, 0)
5 (100006, ‘龍龍’, 2)
2. MySQL實現
drop table if exists UserUser;
create table UserUser(
user_id int primary key,
user_name varchar(25),
user_type int
);
insert into UserUser values(100001,'彭彭',0);
insert into UserUser values(100002,'玉玉',0);
insert into UserUser values(100003,'小青',0);
insert into UserUser values(100004,'健健',0);
insert into UserUser values(100005,'靜靜',0);
insert into UserUser values(100006,'龍龍',0);
select * from UserUser;
drop table if exists Game_detail;
create table Game_detail(
day_id date,
user_id int,
game_id int,
duration int,
primary key(day_id,user_id,game_id),
foreign key(user_id) references UserUser(user_id)
);
insert into Game_detail values('2018-10-20',100001,1011,100);
insert into Game_detail values('2018-10-21',100002,1011,100);
insert into Game_detail values('2018-10-22',100003,1012,90);
insert into Game_detail values('2018-1-20',100004,1013,60);
insert into Game_detail values('2018-3-20',100005,1014,170);
insert into Game_detail values('2018-10-21',100006,1011,100);
insert into Game_detail values('2018-12-2',100001,1011,100);
insert into Game_detail values('2018-10-21',100002,1014,100);
insert into Game_detail values('2018-10-20',100003,1015,90);
insert into Game_detail values('2018-3-14',100005,1012,170);
insert into Game_detail values('2018-10-25',100006,1012,100);
insert into Game_detail values('2018-11-20',100001,1017,100);
insert into Game_detail values('2018-10-27',100002,1015,100);
insert into Game_detail values('2018-10-24',100003,1014,90);
insert into Game_detail values('2018-3-10',100005,1013,170);
insert into Game_detail values('2018-10-23',100006,1013,100);
insert into Game_detail values('2018-11-20',100001,1011,100);
insert into Game_detail values('2018-10-29',100002,1014,100);
insert into Game_detail values('2018-10-14',100003,1015,90);
insert into Game_detail values('2018-3-20',100005,1012,170);
insert into Game_detail values('2018-10-20',100006,1017,100);
insert into Game_detail values('2018-8-20',100001,1018,100);
insert into Game_detail values('2018-9-20',100002,1019,100);
insert into Game_detail values('2018-10-20',100003,1014,90);
insert into Game_detail values('2018-3-20',100005,1013,170);
insert into Game_detail values('2018-10-24',100006,1014,100);
insert into Game_detail values('2018-1-20',100003,1013,90);
insert into Game_detail values('2018-3-20',100005,1011,170);
insert into Game_detail values('2018-10-23',100006,1012,100);
insert into Game_detail values('2018-10-24',100006,1013,100);
insert into Game_detail values('2018-10-28',100006,1015,100);
insert into Game_detail values('2018-10-29',100006,1019,100);
insert into Game_detail values('2018-11-22',100006,1017,100);
select * from Game_detail;
-- 篩選統計每個人玩的遊戲數量
select UserUser.user_id as uid,count(distinct game_id) as cnt from UserUser
join Game_detail on UserUser.user_id=Game_detail.user_id
group by UserUser.user_id;
-- update User表中的user_type欄位
update UserUser join
(select UserUser.user_id as uid,count(distinct game_id) as cnt from UserUser
join Game_detail on UserUser.user_id=Game_detail.user_id
group by UserUser.user_id) as tmp
on UserUser.user_id=tmp.uid
set user_type=(
case
when tmp.cnt<3 then 0
when tmp.cnt between 3 and 6 then 1
when tmp.cnt>6 then 2
end);
select * from UserUser;
或者:
update UserUser as u
set u.user_type =
(select
case when ct > 6 then 2
when ct < 3 then 0
else 1 end
from (select user_id, count(distinct game_id) ct
from Game_detail
group by user_id) as g #派生表都要給它起個名字
where u.user_id=g.user_id);
- Oracle實現
merge into UserUser u
using (select user_id, count(distinct game_id) ct
from game_details
group by user_id) g
on (u.user_id=g.user_id)
when matched then
update
set u.user_type=(
case
when ct > 6 then 2
when ct < 3 then 0
else 1 end
)
- SQLserver版本
//user是SQLserver的保留變數 不能做表名.update語句不支援別名
update Users
set user_type =
(select case
when ct > 6 then 2
when ct < 3 then 0
else 1 end
from (select user_id, count(distinct game_id) ct
from Game_detail
group by user_id) g
where Users.user_id = g.user_id);