關於hive當中獲取時間的操作。


今天突然在網上看到別人的面試題,覺得有點好奇想做一下,突然發現sql server的語法對於hive是不適用的。於是各種查資料。

然后發現hive中沒有直接獲取到當前時間的函數,而且對於時間定義的函數特別少,問題解決起來還是有難度。

下面介紹hive獲取時間的方式:

題目給定一張表(列有月份,銷售額),要求查詢出月份、本月銷售額、上月銷售額這三個結果,如果當月上個月的銷售額不存在就顯示為“*”。

看到這個我第一個想到的就是根據時間來進行分組然后累加求和,然后對分組累加的數據按照月份進行排序,取出前兩條數據,然后結束。

看起來思路是對的,可是實際推敲有很多的問題。

(1)比如給定的時間是帶日期的並不是按照月份來分的。比如 2018-08-12 像這種的額么分組。還是要將日期進行截取,然后分組累加才行。

(2)題目是獲取到當前月份和上個月的數據。萬一表中沒有存當前的月份,上個月的也沒有存怎么辦。獲取的數據不就不准確了。

針對上面的問題我們肯定要對日期進行截取,然后分組累加,這是毋庸置疑的。另外就是要限定死當前月份和上個月的額月份。然后用限定死的月份去和表中的數據進行join操作

然后問題來了:在寫hql的時候發現各種問題,hive獲取時間的操作都很少。

SELECT FROM_UNIXTIME(UNIX_TIMESTAMP());  hive是通過獲取到時間戳的形式來獲取到時間,然后通過函數FROM_UNIXTIME 轉化為日期時間的形式。
OK 2018-08-12 19:02:58

然后通過substr()函數獲取到當前的月份;

  SELECT SUBSTR(FROM_UNIXTIME(UNIX_TIMESTAMP()),1,7) AS mo;
   OK
  2018-08

這下問題來了。獲取到了當期的日期怎么獲取到上個月的時間那。嘗試用下面的函數進行獲取;

SELECT SUBSTR(DATE_SUB(FROM_UNIXTIME(UNIX_TIMESTAMP()),30),1,7) AS mo  

通過DATE_SUB()函數對獲取的時間戳進行操作,對日期進行相減,突然發現要得到上個月的時間,我們的月份的時間都不確定,這里用30天,肯定不行。

有開始發現新的方法:

 SELECT SUBSTR(DATE_SUB(FROM_UNIXTIME(UNIX_TIMESTAMP()),DAYOFMONTH(FROM_UNIXTIME(UNIX_TIMESTAMP()))),1,7) AS mo

還是使用的DATE_SUB對日期進行操作,這次是將后面那個參數設置為獲取到當前的日期,相減就是上個月最后一天,也是代表上個月。

於是問題得到了解決;

下面是改造完成的sql:

WITH  mon AS (

     SELECT SUBSTR(FROM_UNIXTIME(UNIX_TIMESTAMP()),1,7) AS mo
     UNION ALL
     SELECT SUBSTR(DATE_SUB(FROM_UNIXTIME(UNIX_TIMESTAMP()),DAYOFMONTH(FROM_UNIXTIME(UNIX_TIMESTAMP()))),1,7) AS mo

)  --這里采用了with as的形式對經常操作的數據進行存儲,起到的相當於中間表的作用。

    SELECT
    mo AS mth,
    CASE WHEN SUM(nvl(AMOUNT,0))=0 THEN '*'
    ELSE
    CAST(SUM(nvl(AMOUNT,0) AS VARCHAR(10))) END AS SUM_AMOUN
    FROM
    mon
    LEFT JOIN tb2 ON mo=SUBSTR(SALEDATE,1,7)
    GROUP BY mo;

對臨用左連接的方式去連接主表,然后進行查詢。

 

對於Hive 的函數。有時候真的很麻煩。有時候還需要自定義函數進行操作。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM