Hive sql語句必練50題-入門到精通(2)
原始鏈接:https://blog.csdn.net/Thomson617/article/details/83280617
原創Thomson617 最後發佈於2018-10-22 23:08:54 閱讀數 2546 收藏
展開
承接: Hive sql語句必練50題-入門到精通(1)
– 21、查詢不同老師所教不同課程平均分從高到低顯示:
– 方法1
select course.c_id,course.t_id,t_name,round(avg(s_score),2)as avgscore from course
join teacher on teacher.t_id=course.t_id
join score on course.c_id=score.c_id
group by course.c_id,course.t_id,t_name order by avgscore desc;
1
2
3
4
– 方法2
select course.c_id,course.t_id,t_name,round(avg(s_score),2)as avgscore from course,teacher,score
where teacher.t_id=course.t_id and course.c_id=score.c_id
group by course.c_id,course.t_id,t_name order by avgscore desc;
1
2
3
– 22、查詢所有課程的成績第2名到第3名的學生信息及該課程成績:
select tmp1.* from
(select * from score where c_id='01' order by s_score desc limit 3)tmp1
order by s_score asc limit 2
union all select tmp2.* from
(select * from score where c_id='02' order by s_score desc limit 3)tmp2
order by s_score asc limit 2
union all select tmp3.* from
(select * from score where c_id='03' order by s_score desc limit 3)tmp3
order by s_score asc limit 2;
1
2
3
4
5
6
7
8
9
– 23、統計各科成績各分數段人數:課程編號,課程名稱,[100-85],[85-70],[70-60],[0-60]及所佔百分比
select c.c_id,c.c_name,tmp1.s0_60, tmp1.percentum,tmp2.s60_70, tmp2.percentum,tmp3.s70_85, tmp3.percentum,tmp4.s85_100, tmp4.percentum
from course c
join(select c_id,sum(case when s_score<60 then 1 else 0 end )as s0_60,
round(100*sum(case when s_score<60 then 1 else 0 end )/count(c_id),2)as percentum
from score group by c_id)tmp1 on tmp1.c_id =c.c_id
left join(select c_id,sum(case when s_score<70 and s_score>=60 then 1 else 0 end )as s60_70,
round(100*sum(case when s_score<70 and s_score>=60 then 1 else 0 end )/count(c_id),2)as percentum
from score group by c_id)tmp2 on tmp2.c_id =c.c_id
left join(select c_id,sum(case when s_score<85 and s_score>=70 then 1 else 0 end )as s70_85,
round(100*sum(case when s_score<85 and s_score>=70 then 1 else 0 end )/count(c_id),2)as percentum
from score group by c_id)tmp3 on tmp3.c_id =c.c_id
left join(select c_id,sum(case when s_score>=85 then 1 else 0 end )as s85_100,
round(100*sum(case when s_score>=85 then 1 else 0 end )/count(c_id),2)as percentum
from score group by c_id)tmp4 on tmp4.c_id =c.c_id;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
– 24、查詢學生平均成績及其名次:
select tmp.*,row_number()over(order by tmp.avgScore desc) Ranking from
(select student.s_id,
student.s_name,
round(avg(score.s_score),2) as avgScore
from student join score
on student.s_id=score.s_id
group by student.s_id,student.s_name)tmp
order by avgScore desc;
1
2
3
4
5
6
7
8
– 25、查詢各科成績前三名的記錄
–課程id爲01的前三名
select score.c_id,course.c_name,student.s_name,s_score from score
join student on student.s_id=score.s_id
join course on score.c_id='01' and course.c_id=score.c_id
order by s_score desc limit 3;
1
2
3
4
–課程id爲02的前三名
select score.c_id,course.c_name,student.s_name,s_score
from score
join student on student.s_id=score.s_id
join course on score.c_id='02' and course.c_id=score.c_id
order by s_score desc limit 3;
1
2
3
4
5
–課程id爲03的前三名
select score.c_id,course.c_name,student.s_name,s_score
from score
join student on student.s_id=score.s_id
join course on score.c_id='03' and course.c_id=score.c_id
order by s_score desc limit 3;
1
2
3
4
5
– 26、查詢每門課程被選修的學生數:
select c.c_id,c.c_name,tmp.number from course c
join (select c_id,count(1) as number from score
where score.s_score<60 group by score.c_id)tmp
on tmp.c_id=c.c_id;
1
2
3
4
– 27、查詢出只有兩門課程的全部學生的學號和姓名:
select st.s_id,st.s_name from student st
join (select s_id from score group by s_id having count(c_id) =2)tmp
on st.s_id=tmp.s_id;
1
2
3
– 28、查詢男生、女生人數:
select tmp1.man,tmp2.women from
(select count(1) as man from student where s_sex='男')tmp1,
(select count(1) as women from student where s_sex='女')tmp2;
1
2
3
– 29、查詢名字中含有"風"字的學生信息:
select * from student where s_name like '%風%';
1
– 30、查詢同名同性學生名單,並統計同名人數:
select s1.s_id,s1.s_name,s1.s_sex,count(*) as sameName
from student s1,student s2
where s1.s_name=s2.s_name and s1.s_id<>s2.s_id and s1.s_sex=s2.s_sex
group by s1.s_id,s1.s_name,s1.s_sex;
1
2
3
4
– 31、查詢1990年出生的學生名單:
select * from student where s_birth like '1990%';
1
– 32、查詢每門課程的平均成績,結果按平均成績降序排列,平均成績相同時,按課程編號升序排列:
select score.c_id,c_name,round(avg(s_score),2) as avgScore from score
join course on score.c_id=course.c_id
group by score.c_id,c_name order by avgScore desc,score.c_id asc;
1
2
3
– 33、查詢平均成績大於等於85的所有學生的學號、姓名和平均成績:
select score.s_id,s_name,round(avg(s_score),2)as avgScore from score
join student on student.s_id=score.s_id
group by score.s_id,s_name having avg(s_score) >= 85;
1
2
3
– 34、查詢課程名稱爲"數學",且分數低於60的學生姓名和分數:
select s_name,s_score as mathScore from student
join (select s_id,s_score
from score,course
where score.c_id=course.c_id and c_name='數學')tmp
on tmp.s_score < 60 and student.s_id=tmp.s_id;
1
2
3
4
5
– 35、查詢所有學生的課程及分數情況:
select a.s_name,
SUM(case c.c_name when '語文' then b.s_score else 0 end ) as chainese,
SUM(case c.c_name when '數學' then b.s_score else 0 end ) as math,
SUM(case c.c_name when '英語' then b.s_score else 0 end ) as english,
SUM(b.s_score) as sumScore
from student a
join score b on a.s_id=b.s_id
join course c on b.c_id=c.c_id
group by s_name,a.s_id;
1
2
3
4
5
6
7
8
9
後續部分參見:
https://blog.csdn.net/Thomson617/article/details/83281254
Hive下的SQL經驗總結:
(1).不支持非等值連接,一般使用left join、right join 或者inner join替代。
•SQL中對兩表內聯可以寫成:
select * from dual a,dual b where a.key = b.key;
•Hive中應爲:
select * from dual a join dual b on a.key = b.key;
而不是傳統的格式:
SELECT t1.a1 as c1, t2.b1 as c2 FROM t1, t2 WHERE t1.a2 = t2.b2
(2).分號字符:不能智能識別concat(‘;’,key),只會將‘;’當做SQL結束符號。
•分號是SQL語句結束標記,在HiveQL中也是,但是在HiveQL中,對分號的識別沒有那麼智慧,例如:
•select concat(key,concat(';',key)) from dual;
•但HiveQL在解析語句時提示:
FAILED: Parse Error: line 0:-1 mismatched input '<EOF>' expecting ) in function specification
•解決的辦法是,使用分號的八進制的ASCII碼進行轉義,那麼上述語句應寫成:
•select concat(key,concat('\073',key)) from dual;
(3).不支持INSERT INTO 表 Values(), UPDATE, DELETE等操作.這樣的話,就不要很複雜的鎖機制來讀寫數據。
INSERT INTO syntax is only available starting in version 0.8。INSERT INTO就是在表或分區中追加數據。
(4).HiveQL中String類型的字段若是空(empty)字符串, 即長度爲0, 那麼對它進行IS NULL的判斷結果是False,使用left join可以進行篩選行。
(5).不支持 ‘< dt <’這種格式的範圍查找,可以用dt in(”,”)或者between替代。
(6).Hive不支持將數據插入現有的表或分區中,僅支持覆蓋重寫整個表,示例如下:
INSERT OVERWRITE TABLE t1 SELECT * FROM t2;
(7).group by的字段,必須是select後面的字段,select後面的字段不能比group by的字段多.
如果select後面有聚合函數,則該select語句中必須有group by語句;
而且group by後面不能使用別名;
有聚合函數存在就必須有group by.
(8).select , where 及 having 之後不能跟子查詢語句(一般使用left join、right join 或者inner join替代)
(9).先join(及inner join) 然後left join或right join
(10).hive不支持group_concat方法,可用 concat_ws('|', collect_set(str)) 實現
(11).not in 和 <> 不起作用,可用left join tmp on tableName.id = tmp.id where tmp.id is null 替代實現
(12).hive 中‘不等於’不管是用! 或者<>符號實現,都會將空值即null過濾掉,此時要用
where (white_level<>'3' or white_level is null)
或者 where (white_level!='3' or white_level is null ) 來保留null 的情況。
(13).union all 後面的表不加括號,不然執行報錯;
hive也不支持頂層的union all,使用子查詢來解決;
union all 之前不能有DISTRIBUTE BY | SORT BY| ORDER BY | LIMIT 等查詢條件