『壹』 Hive sql及窗口函數
hive函數:
  
 1、根據指定條件返回結果:case when then else end as
                                          
 2、基本類型轉換:CAST()
  
 3、nvl:處理空欄位:三個str時,是否為空可以指定返回不同的值
  
 4、sql通配符: https://www.w3school.com.cn/sql/sql_wildcards.asp 
  
 5、count(1)與COUNT(*):返回行數
  
 如果表沒有主鍵,那麼count(1)比count(*)快;
  
 如果有主鍵,那麼count(主鍵,聯合主鍵)比count(*)快;
  
 count(1)跟count(主鍵)一樣,只掃描主鍵。count(*)跟count(非主鍵)一樣,掃描整個表。明顯前者更快一些。
  
 性能問題:
  
 1.任何情況下SELECT COUNT(*) FROM tablename是最優選擇,(指沒有where的情況);
  
 2.盡量減少SELECT COUNT(*) FROM tablename WHERE COL = 『value』 這種查詢;
  
 3.杜絕SELECT COUNT(COL) FROM tablename WHERE COL2 = 『value』 的出現。
  
 count(expression):查詢 is_reply=0 的數量: SELECT COUNT(IF(is_reply=0,1,NULL)) count FROM t_iov_help_feedback;
  
 6、distinct與group by
  
 distinct去重所有distinct之後所有的欄位,如果有一個欄位值不一致就不作為一條
  
 group by是根據某一欄位分組,然後查詢出該條數據的所需欄位,可以搭配 where max(time)或者Row_Number函數使用,求出最大的一條數據
  
 7、使用with 臨時表名 as() 的形式,簡單的臨時表直接嵌套進sql中,復雜的和需要復用的表寫到臨時表中,關聯的時候先找到關聯欄位,過濾條件最好在臨時表中先過濾後關聯
  
 處理json的函數:
  
 split(json_array_string(schools), '\\|\\|') AS schools
  
 get_json_object(school, '$.id') AS school_id,
  
 字元串函數:
  
 1、instr(』源字元串』 , 『目標字元串』 ,』開始位置』,』第幾次出現』)
  
 instr(sourceString,destString,start,appearPosition)
  
 1.sourceString代表源字元串; destString代表要從源字元串中查找的子串;
  
 2.start代表查找的開始位置,這個參數可選的,默認為1;
  
 3.appearPosition代表想從源字元中查找出第幾次出現的destString,這個參數也是可選的, 默認為1
  
 4.如果start的值為負數,則代表從右往左進行查找,但是位置數據仍然從左向右計算。
  
 5.返回值為:查找到的字元串的位置。如果沒有查找到,返回0。
  
 最簡單例子: 在abcd中查找a的位置,從第一個字母開始查,查找第一次出現時的位置
  
 select instr(『abcd』,』a』,1,1) from al; —1
  
 應用於模糊查詢:instr(欄位名/列名, 『查找欄位』)
  
 select code,name,dept,occupation from staff where instr(code, 『001』)> 0;
  
 等同於 select code, name, dept, occupation from staff where code like 『%001%』 ;
  
 應用於判斷包含關系:
  
 select ccn,mas_loc from mas_loc where instr(『FH,FHH,FHM』,ccn)>0;
  
 等同於 select ccn,mas_loc from mas_loc where ccn in (『FH』,』FHH』,』FHM』);
  
 2、substr(string A,int start,int len)和 substring(string A,int start,int len),用法一樣
  
 substr(time,1,8) 表示將time從第1位開始截取,截取的長度為8位
  
 第一種用法:
  
 substr(string A,int start)和 substring(string A,int start),用法一樣
  
 功效:返回字元串A從下標start位置到結尾的字元串
  
 第二種用法:
  
 substr(string A,int start,int len)和 substring(string A,int start,int len),用法一樣
  
 功效:返回字元串A從下標start位置開始,長度為len的字元串
  
 3、get_json_object(form_data,'$.學生姓名') as student_name
  
 json_tuple 函數的作用:用來解析json字元串中的多個欄位
                                          
 4、split(full_name, '\\.') [5] AS zq;   取的是數組里的第六個
  
 日期(時間)函數:
  
 1、to_date(event_time) 返回日期部分
  
 2、date_sub:返回當前日期的相對時間
  
 當前日期:select curdate() 
  
 當前日期前一天:select  date_sub(curdate(),interval 1 day)
  
 當前日期後一天:select date_sub(curdate(),interval -1 day)
  
 date_sub(from_unixtime(unix_timestamp(), 'yyyy-MM-dd HH:mm:ss'), 14)  將現在的時間總秒數轉為標准格式時間,返回14天之前的時間
  
 時間戳>>>>日期:
  
 from_unixtime(unix_timestamp(), 'yyyy-MM-dd HH:mm:ss') 將現在的時間總秒數轉為標准格式時間
  
 from_unixtime(get_json_object(get_json_object(form_data,'$.挽單時間'),'$.$date')/1000) as retain_time
  
 unix_timestamp('2019-08-15 16:40:00','yyyy-MM-dd HH:mm:ss')   --1565858400
  
 日期>>>>時間戳:unix_timestamp()
  
 date_format:yyyy-MM-dd HH:mm:ss 時間轉格式化時間
  
 select date_format('2019-10-07 13:24:20', 'yyyyMMdd000000')-- 20191007000000select date_format('2019-10-07', 'yyyyMMdd000000')-- 20191007000000
  
 1.日期比較函數: datediff語法: datediff(string enddate,string startdate) 
  
 返回值: int 
  
 說明: 返回結束日期減去開始日期的天數。 
  
 舉例:  hive> select datediff('2016-12-30','2016-12-29');  1
  
 2.日期增加函數: date_add語法: date_add(string startdate, intdays) 
  
 返回值: string 
  
 說明: 返回開始日期startdate增加days天後的日期。 
  
 舉例:  hive>select date_add('2016-12-29',10);  2017-01-08
  
 3.日期減少函數: date_sub語法: date_sub (string startdate,int days) 
  
 返回值: string 
  
 說明: 返回開始日期startdate減少days天後的日期。 
  
 舉例:  hive>select date_sub('2016-12-29',10);  2016-12-19
  
 4.查詢近30天的數據
  
 select * from table where datediff(current_timestamp,create_time)<=30;
  
 create_time 為table里的欄位,current_timestamp 返回當前時間 2018-06-01 11:00:00
  
 3、trunc()函數的用法:當前日期的各種第一天,或者對數字進行不四捨五入的截取
  
 日期:
  
 1.select trunc(sysdate) from al  --2011-3-18  今天的日期為2011-3-18
  
 2.select trunc(sysdate, 'mm')   from   al  --2011-3-1    返回當月第一天.
  
 上月1號     trunc(add_months(current_date(),-1),'MM')
  
 3.select trunc(sysdate,'yy') from al  --2011-1-1       返回當年第一天
  
 4.select trunc(sysdate,'dd') from al  --2011-3-18    返回當前年月日
  
 5.select trunc(sysdate,'yyyy') from al  --2011-1-1   返回當年第一天
  
 6.select trunc(sysdate,'d') from al  --2011-3-13 (星期天)返回當前星期的第一天
  
 7.select trunc(sysdate, 'hh') from al   --2011-3-18 14:00:00   當前時間為14:41  
  
 8.select trunc(sysdate, 'mi') from al  --2011-3-18 14:41:00   TRUNC()函數沒有秒的精確
  
 數字:TRUNC(number,num_digits) Number 需要截尾取整的數字。Num_digits 的默認值為 0。TRUNC()函數截取時不進行四捨五入
  
 11.select trunc(123.458,1) from al --123.4
  
 12.select trunc(123.458,-1) from al --120
  
 4、round():四捨五入:
  
 select round(1.455, 2)  #結果是:1.46,即四捨五入到十分位,也就是保留兩位小數
  
 select round(1.5)  #默認四捨五入到個位,結果是:2
  
 select round(255, -1)  #結果是:260,即四捨五入到十位,此時個位是5會進位
  
 floor():地板數
  
 ceil()天花板數
  
 5、
  
 6.日期轉年函數: year語法:   year(string date) 
  
 返回值: int
  
 說明: 返回日期中的年。
  
 舉例:
  
 hive>   select year('2011-12-08 10:03:01') from al;
  
 2011
  
 hive>   select year('2012-12-08') fromal;
  
 2012
  
 7.日期轉月函數: month語法: month   (string date) 
  
 返回值: int
  
 說明: 返回日期中的月份。
  
 舉例:
  
 hive>   select month('2011-12-08 10:03:01') from al;
  
 12
  
 hive>   select month('2011-08-08') fromal;
  
 8
  
 8.日期轉天函數: day語法: day   (string date) 
  
 返回值: int
  
 說明: 返回日期中的天。
  
 舉例:
  
 hive>   select day('2011-12-08 10:03:01') from al;
  
 8
  
 hive>   select day('2011-12-24') fromal;
  
 24
  
 9.日期轉小時函數: hour語法: hour   (string date) 
  
 返回值: int
  
 說明: 返回日期中的小時。
  
 舉例:
  
 hive>   select hour('2011-12-08 10:03:01') from al;
  
 10
  
 10.日期轉分鍾函數: minute語法: minute   (string date) 
  
 返回值: int
  
 說明: 返回日期中的分鍾。
  
 舉例:
  
 hive>   select minute('2011-12-08 10:03:01') from al;
  
 3
  
 11.日期轉秒函數: second語法: second   (string date) 
  
 返回值: int
  
 說明: 返回日期中的秒。
  
 舉例:
  
 hive>   select second('2011-12-08 10:03:01') from al;
  
 1
  
 12.日期轉周函數: weekofyear語法:   weekofyear (string date) 
  
 返回值: int
  
 說明: 返回日期在當前的周數。
  
 舉例:
  
 hive>   select weekofyear('2011-12-08 10:03:01') from al;
  
 49
  
 查看hive表在hdfs中的位置:show create table 表名;
  
 在hive中hive2hive,hive2hdfs:
  
 HDFS、本地、hive -----> Hive:使用 insert into | overwrite、loaddata local inpath "" into table student;
  
 Hive ----> Hdfs、本地:使用:insert overwrite | local
  
 網站訪問量統計:
  
 uv:每用戶訪問次數
  
 ip:每ip(可能很多人)訪問次數
  
 PV:是指頁面的瀏覽次數
  
 VV:是指你訪問網站的次數
  
 sql:
                                          
 基本函數:
  
 count、max、min、sum、avg、like、rlike('2%'、'_2%'、%2%'、'[2]')(java正則)
  
 and、or、not、in   
  
 where、group by、having、{ join on 、full join}  、order by(desc降序)
                                          
 sort by需要與distribut by集合結合使用:
  
 hive (default)> set maprece.job.reces=3;  //先設置rece的數量 
  
 insert overwrite local directory '/opt/mole/datas/distribute-by'
  
 row format delimited fields terminated by '\t'
  
 先按照部門編號分區,再按照員工編號降序排序。
  
 select * from emp distribute by deptno sort by empno desc;
  
 外部表  create external table if not exists dept
  
 分區表:create table dept_partition ( deptno int, dname string, loc string )  partitioned by ( month string )
  
 load data local inpath '/opt/mole/datas/dept.txt' into table default.dept_partition partition(month='201809'); 
  
  alter table dept_partition add/drop partition(month='201805') ,partition(month='201804');
  
 多分區聯合查詢:union
  
 select * from dept_partition2 where month='201809' and day='10';
  
 show partitions dept_partition;
  
 desc formatted dept_partition;
  
 二級分區表:create table dept_partition2 ( deptno int, dname string, loc string ) partitioned by (month string, day string) row format delimited fields terminated by '\t';
  
 分桶抽樣查詢:分區針對的是數據的存儲路徑;分桶針對的是數據文件
  
 create table stu_buck(id int, name string) clustered by(id) into 4 bucketsrow format delimited fields terminated by '\t';
  
 設置開啟分桶與rece為1:
  
 set hive.enforce.bucketing=true;
  
 set maprece.job.reces=-1;
  
 分桶抽樣:select * from stu_bucktablesample(bucket x out of y on id);
  
 抽取,桶數/y,x是從哪個桶開始抽取,y越大 抽樣數越少,y與抽樣數成反比,x必須小於y
  
 給空欄位賦值:
  
 如果員工的comm為NULL,則用-1代替或用其他欄位代替  :select nvl(comm,-1) from emp;
  
 case when:如何符合記為1,用於統計、分組統計
  
 select dept_id, sum(case sex when '男' then 1 else 0 end) man , sum(case sex when '女' then 1 else 0 end) woman from emp_sex group by dept_id;
  
 用於組合歸類匯總(行轉列):UDAF:多轉一
  
 concat:拼接查詢結果
  
 collect_set(col):去重匯總,產生array類型欄位,類似於distinct
  
 select t.base, concat_ws('|',collect_set(t.name))   from (select concat_ws(',',xingzuo,blood_type) base,name  from person_info) t group by t.base;
  
 解釋:先第一次查詢得到一張沒有按照(星座血型)分組的表,然後分組,使用collect_set將名字組合成數組,然後使用concat將數組變成字元串
  
 用於拆分數據:(列轉行):UDTF:一轉多
  
 explode(col):將hive一列中復雜的array或者map結構拆分成多行。
  
 lateral view  側面顯示:用於和UDTF一對多函數搭配使用
  
 用法:lateral view udtf(expression) tablealias as cate
  
 cate:炸開之後的列別名
  
 temptable :臨時表表名
  
 解釋:用於和split, explode等UDTF一起使用,它能夠將一列數據拆成多行數據,在此基礎上可以對拆分後的數據進行聚合。
  
 開窗函數:
  
 Row_Number,Rank,Dense_Rank  over:針對統計查詢使用
                                          
 Row_Number:返回從1開始的序列
  
 Rank:生成分組中的排名序號,會在名詞s中留下空位。3 3 5
  
 dense_rank:生成分組中的排名序號,不會在名詞中留下空位。3 3 4
  
 over:主要是分組排序,搭配窗口函數使用
  
 結果:
                                          
 SUM、AVG、MIN、MAX、count
                                          
 preceding:往前
  
 following:往後
  
 current row:當前行
  
 unbounded:unbounded preceding 從前面的起點, unbounded following:到後面的終點
  
 sum:直接使用sum是總的求和,結合over使用可統計至每一行的結果、總的結果、當前行+之前多少行/之後多少行、當前行到往後所有行的求和。
  
 over(rowsbetween 3/current  )  當前行到往後所有行的求和
  
 ntile:分片,結合over使用,可以給數據分片,返回分片號
                                          
 使用場景:統計出排名前百分之或n分之一的數據。
  
 lead,lag,FIRST_VALUE,LAST_VALUE
  
 lag與lead函數可以返回上下行的數據
                                          
 lead(col,n,dafault) 用於統計窗口內往下第n行值
  
 第一個參數為列名,第二個參數為往下第n行(可選,默認為1),第三個參數為默認值(當往下第n行為NULL時候,取默認值,如不指定,則為NULL)
  
 LAG(col,n,DEFAULT) 用於統計窗口內往上第n行值
  
 第一個參數為列名,第二個參數為往上第n行(可選,默認為1),第三個參數為默認值(當往上第n行為NULL時候,取默認值,如不指定,則為NULL)
  
 使用場景:通常用於統計某用戶在某個網頁上的停留時間
  
 FIRST_VALUE:取分組內排序後,截止到當前行,第一個值
  
 LAST_VALUE:取分組內排序後,截止到當前行,最後一個值
  
 范圍內求和:  https://blog.csdn.net/happyrocking/article/details/105369558 
  
 cume_dist,percent_rank
                                          
 –CUME_DIST :小於等於當前值的 行數 / 分組內總行數
  
 –比如,統計小於等於當前薪水的人數,占總人數的比例
  
 percent_rank:分組內當前行的RANK值-1/分組內總行數-1
  
 總結:
  
 在Spark中使用spark sql與hql一致,也可以直接使用sparkAPI實現。
  
 HiveSql窗口函數主要應用於求TopN,分組排序TopN、TopN求和,前多少名前百分之幾。
  
 與Flink窗口函數不同。
  
 Flink中的窗口是用於將無線數據流切分為有限塊處理的手段。
  
 window分類:
  
 CountWindow:按照指定的數據條數生成一個 Window,與時間無關。
  
 TimeWindow:按照時間生成 Window。
  
 1. 滾動窗口(Tumbling Windows):時間對齊,窗口長度固定,不重疊::常用於時間段內的聚合計算
  
 2.滑動窗口(Sliding Windows):時間對齊,窗口長度固定,可以有重疊::適用於一段時間內的統計(某介面最近 5min 的失敗率來報警)
  
 3. 會話窗口(Session Windows)無時間對齊,無長度,不重疊::設置session間隔,超過時間間隔則窗口關閉。
『貳』 mysql中字元串的拼接,能不能不使用concat函數
能使用。
MySQL concat函數可以連接一個或者多個字元串,如
select concat('10');
結果:10 
select concat('11','22','33');
結果
112233
MySQL的concat函數在連接字元串的時候,只要其中一個是NULL,那麼將返回NULL
select concat('11','22',null);
結果
NULL
『叄』 mysql中convert()函數是什麼意思
mysql中convert()函數的意思是用來把一個數據類型的值轉換為另一個數據類型。
其他函數:
ASCII(s)
作用: 返回字元串 s 的第一個字元的 ASCII 碼。
CHAR_LENGTH(s)
作用: 返回字元串 s 的字元數。
CHARACTER_LENGTH(s)
作用: 返回字元串 s 的字元數。
CONCAT(s1,s2...sn)  作用: 字元串 s1,s2 等多個字元串合並為一個字元串  。
CONCAT_WS(x, s1,s2...sn)  作用: 同 CONCAT(s1,s2,...) 函數,但是每個字元串之間要加上 x,x 可以是分隔符 。
FIELD(s,s1,s2...) 作用: 返回第一個字元串 s 在字元串列表(s1,s2...)中的位置 。

(3)sqlconcatws擴展閱讀:
MySQL 中文排序錯誤的解決方法
方法1
在 MySQL 資料庫中,進行中文排序和查找的時候,對漢字的排序和查找結果是錯誤的。這種情況在 MySQL 的很多版本中都存在。如果這個問題不解決,那麼 MySQL 將無法實際處理中文。
出現這個問題的原因是:MySQL 
在查詢字元串時是大小寫不敏感的,在編繹 MySQL 時一般以 ISO-8859 
字元集作為默認的字元集,因此在比較過程中中文編碼字元大小寫轉換造成了這種現象,一種解決方法是對於包含中文的欄位加上 "binary" 
屬性,使之作為二進制比較,
例如將 "name char(10)" 改成 "name char(10)binary"。
方法2
如果你使用源碼編譯 MySQL,可以編譯 MySQL 時使用 --with--charset=gbk 參數,這樣 MySQL 就會直接支持中文查找和排序了。
『肆』 mysql中的concat用法!
這個sql語句是指從資料庫表裡面拼接組合goods_sn,goods_title,goods_brief,goods_name 有包含tablet欄位的數據。等價於goods_sn||goods_title||goods_brief||goods_name LIKE '%tablet%。
concat 等同於字元串連接符 ||,concat(字串1, 字串2, 字串3, ...),將字串1、字串2、字串3,等字串連在一起。

(4)sqlconcatws擴展閱讀:
MySQL,Oracle,SQL Server拼接字元串查詢示例:
例子1:
MySQL:
SELECT CONCAT(region_name,store_name) FROM Geography WHERE store_name = 'Boston';
例子2:
Oracle:
SELECT region_name || ' ' || store_name FROM Geography WHERE store_name = 'Boston';
例子3:
SQL Server:
SELECT region_name + ' ' + store_name FROM Geography WHERE store_name = 'Boston';
