Hive sql語句必練50題-入門到精通(2)(轉載)

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 等查詢條件

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