mysql一道面试题目的详细分析,求同标签下男女分别多少人

题目:用户表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

 

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章