hive sql 基本練習
表的結構
create table student(Sno int,Sname string,Sex string,Sage int,Sdept string)
row format delimited fields terminated by ','stored as textfile;
create table course(Cno int,Cname string) row format delimited fields terminated by ',' stored as textfile;create table sc(Sno int,Cno int,Grade
//selct from 這個英文語句就可以看出是先做 from後面的操作,然後再做select操作將其取出來,還是要按照歪果仁的思維來思考問題
查詢全體學生的學號與姓名
select Sno, Sname from student;查詢選修了課程的學生姓名
select Sname from student s where s.Sdept is not null;
----hive的group by 和集合函式
查詢學生的總人數
select count(*) from student; //
計算1號課程的學生平均成績
select avg(s.Grade) from sc s where s.Grade = 1;
查詢各科成績平均分
查詢選修1號課程的學生最高分數
select grade from sc where cno=1 sort by grade limit 1 //xx這裡是不正確的 因為sort是區域性的並不是全域性的
(注意比較:select * from sc where Cno=1 sort by Grade
select Grade from sc where Cno=1 order by Grade) //order 會將reduce數量強行改為一個,所以order by是全域性的,但是大資料裡面用order by 不利於效率
select cno count(1) from sc group by con //count(1)和count(*)的作用都是一致的,前者稍微快一點
查詢選修了3門以上的課程的學生學號
select sno from sc where count(1)>3 group by son //xx 這是錯的,Having是先分組(這裡的分組指的是group by)在進行篩選,而where是先篩選再進行分組。這裡是先分組再進行的篩選所以要寫成
select sno from sc group by son Having count(1)>3
----hive的Order By/Sort By/Distribute By //sql中只有Order By
Order By ,在strict 模式下(hive.mapred.mode=strict),order by 語句必須跟著limit語句,但是在nonstrict下就不是必須的,這樣做的理由是必須有一個reduce對最終的結果進行排序,如果最後輸出的行數過多,一個reduce需要花費很長的時間。
hive> set hive.mapred.mode=strict; <預設nonstrict>
hive> select Sno from student order by Sno;
FAILED: Error in semantic analysis: 1:33 In strict mode, if ORDER BY is specified, LIMIT must also be specified. Error encountered near token 'Sno'
Sort By,它通常發生在每一個redcue裡,“order by” 和“sort by"的區別在於,前者能給保證輸出都是有順序的,而後者如果有多個reduce的時候只是保證了輸出的部分有序。set mapred.reduce.tasks=<number>在sort by可以指定,在用sort by的時候,如果沒有指定列,它會隨機的分配到不同的reduce裡去。distribute by 按照指定的欄位對資料進行劃分到不同的輸出reduce中
此方法會根據性別劃分到不同的reduce中 ,然後按年齡排序並輸出到不同的檔案中。
查詢學生資訊,結果區分性別按年齡有序hive> set mapred.reduce.tasks=2;(過時) //set mapreduce.job.reduces=2 在hadoop2中有些引數名稱過時了,例如原來的mapred.reduce.tasks
改名為mapreduce.job.reduces
了,當然,這兩個引數你都可以使用,只是第一個引數過時了。
hive> insert overwrite local directory '/home/hadoop/out'
select * from student distribute by Sex sort by Sage;
補充:
儲存select查詢結果的幾種方式:
1、將查詢結果儲存到一張新的hive表中
create table t_tmp
as
select * from t_p;
2、將查詢結果儲存到一張已經存在的hive表中
insert into table t_tmp
select * from t_p;
3、將查詢結果儲存到指定的檔案目錄(可以是本地,也可以是hdfs)
insert overwrite local directory '/home/hadoop/test'
select * from t_p;
4、儲存到hdfs
insert overwrite directory '/aaa/test'select * from t_p;
----Join查詢(老版本只支援等值連線,新的已經可以支援不等值連線)
查詢每個學生及其選修課程的情況
hive> select student.*,sc.* from student join sc on (student.Sno =sc.Sno);
查詢學生的得分情況。
hive>select student.Sname,course.Cname,sc.Grade from student join sc on student.Sno=sc.Sno join course on sc.cno=course.cno; //join兩個表
查詢選修2號課程且成績在90分以上的所有學生。
----LEFT,RIGHT 和 FULL OUTER JOIN (全外連線接) inner join //內連線就是求交集沒有交集的地方不會顯示,要求嚴格些
查詢所有學生的資訊,如果在成績表中有成績,則輸出成績表中的課程號
----LEFT SEMI JOIN Hive當前沒有實現 IN/EXISTS 子查詢,可以用 LEFT SEMI JOIN 重寫子查詢語句。
//HIVE 的semi join效率比innerjoin要高些
重寫以下子查詢SELECT a.key, a.value
FROM a
WHERE a.key in
(SELECT b.key
FROM B);
查詢與“劉晨”在同一個系學習的學生
hive> select s1.Sname from student s1 left semi join student s2 on s1.Sdept=s2.Sdept and s2.Sname='劉晨';
hive 裡面的內建函式