題目:用戶表a, 用戶標籤表b, 現在要達成多對的關係, 還需要做什麼? 查出每個用戶標籤下男女分別多少人?
解析: 已知users tags ; 新建一箇中間表user_tag; 可以想象成愛好
// users
uid name sex
1 aaa 1
2 bbb 1
3 ccc 2
4 ddd 1
5 e 2
// tags
tid name
1 睡覺
2 看書
3 聽歌
4 遊戲
5 跑步
// user_tag
id uid tid
1 1 1
2 1 2
3 1 5
4 2 2
5 2 3
6 3 1
7 3 2
8 3 5
11 4 1
12 4 5
一步步的sql分析
1 以user_tag爲主體, 聯表查詢tags 出內容
select user_tag.id,user_tag.uid,user_tag.tid,tags.name as tag_name from user_tag left join tags on user_tag.tid=tags.tid
id uid tid tag_name
1 1 1 睡覺
2 1 2 看書
3 1 5 跑步
4 2 2 看書
5 2 3 聽歌
6 3 1 睡覺
7 3 2 看書
8 3 5 跑步
11 4 1 睡覺
12 4 5 跑步
2 把上面的當做以個整體, 聯表查詢users; 使3個表合成一個表
select a.id,a.uid,a.tid,a.tag_name,users.name,users.sex from (select user_tag.id,user_tag.uid,user_tag.tid,tags.name as tag_name from user_tag left join tags on user_tag.tid=tags.tid) as a left join users on a.uid=users.uid
id uid tid tag_name name sex
1 1 1 睡覺 aaa 1
2 1 2 看書 aaa 1
3 1 5 跑步 aaa 1
4 2 2 看書 bbb 1
5 2 3 聽歌 bbb 1
6 3 1 睡覺 ccc 2
7 3 2 看書 ccc 2
8 3 5 跑步 ccc 2
11 4 1 睡覺 ddd 1
12 4 5 跑步 ddd 1
3 根據tag分組, 分別計算男女的和
sum(case when sex='1' then 1 else 0 end) as 男生數,
sum(case when sex='2' then 1 else 0 end) as 女生數
最終sql語句如下:
select tid,tag_name,sum(case when sex='1' then 1 else 0 end) as 男生數,
sum(case when sex='2' then 1 else 0 end) as 女生數 from (select a.id,a.uid,a.tid,a.tag_name,users.name,users.sex from (select user_tag.id,user_tag.uid,user_tag.tid,tags.name as tag_name from user_tag left join tags on user_tag.tid=tags.tid) as a left join users on a.uid=users.uid ) as aa group by tag_name;
tid tag_name 男生數 女生數
3 聽歌 1 0
2 看書 2 1
1 睡覺 2 1
5 跑步 2 1
// 優化, 以tags表爲主, 把第一次的left join 變成 right join
select tid,tag_name,sum(case when sex='1' then 1 else 0 end) as 男生數,
sum(case when sex='2' then 1 else 0 end) as 女生數 from (select a.id,a.uid,a.tid,a.tag_name,users.name,users.sex from (select user_tag.id,user_tag.uid,user_tag.tid,tags.name as tag_name from user_tag right join tags on user_tag.tid=tags.tid) as a left join users on a.uid=users.uid ) as aa group by tag_name;
tid tag_name 男生數 女生數
3 聽歌 1 0
遊戲 0 0
2 看書 2 1
1 睡覺 2 1
5 跑步 2 1
// 進一步的優化
select tid,tag_name,sum(case when sex='1' then 1 else 0 end) as 男生數,
sum(case when sex='2' then 1 else 0 end) as 女生數 from (select a.id,a.uid,a.tid,a.tag_name,users.name,users.sex from (select user_tag.id,user_tag.uid,tags.tid,tags.name as tag_name from user_tag right join tags on user_tag.tid=tags.tid) as a left join users on a.uid=users.uid ) as aa group by tag_name order by tid asc;
tid tag_name 男生數 女生數
1 睡覺 2 1
2 看書 2 1
3 聽歌 1 0
4 遊戲 0 0
5 跑步 2 1