1. 程式人生 > >Oracle 按年、月、日、周、季度連續查詢

Oracle 按年、月、日、周、季度連續查詢

1、前言

很多時候,我們需要統計某某狀態下的資料呈現給客戶或者以圖表的方式顯示出來。在按年、月、日、周、季度統計的時候,沒有資料那一年或者那一月、那一天...它是不顯示的。這裡以天舉例,有時候我們需要將每一天的資料都統計出來,哪怕這天該狀態的資料不存在或者說是數量為0,那麼我們怎麼來顯示呢,以下是最近的一些查詢方面的總結,記錄一下,方便以後檢視,也希望能幫助到整有這方面需求的各位朋友。

2、引入

說明:本查詢是在pl/sql下完成

(1)、有時候我們查詢的資料類似下表(按天統計):

Day Num
2017-12-04 1
2017-12-05 2
2017-12-08 4
2017-12-12 3

但是我們需要下面的資料:

Day Num
2017-12-04 2
2017-12-05 3
2017-12-06 0
2017-12-07 1
2017-12-08 0

那麼現在的這個sql怎麼寫呢,有的時候可能會想到NVL()或者ISNULL()(Oracle沒有)等,但是是不是發現一些情況下並不能如意呢?是的,對於我至少是這樣的。那麼請看下面。

3、連續查詢

其實說真的,我不知道叫什麼,所以為了好記憶,起了個“連續查詢”,勿噴啊。

先看一下下面的程式碼:

select floor(to_number(sysdate-to_date('2017-12-18','yyyy-mm-dd'))) as spanDays from dual             --時間差-天
select ceil(MONTHS_BETWEEN
(sysdate,to_date('2017-8-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))) as spanMonths from dual --時間差-月 select floor(to_number(sysdate-to_date('2007-11-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))/365) as spanYears from dual --時間差-年 select ceil(MONTHS_BETWEEN(sysdate,to_date('2017-10-02 15:55:03','yyyy-mm-dd hh24:mi:ss'))/3) as spanMonths from dual --時間差-季度
以上程式碼可以獲取當前時間與指定時間之間的時間差(天,月。。。),至於周就是7天一週,大家得到日期之間相差的天數就可以算了。
那麼我們的查詢就可以和以上查詢結果進行關聯,從而得出每天,每月,每季度。。。的資料,如下:

這裡用到了with語句:

WITH m AS (
SELECT to_char(to_date('2017-12-01','yyyy-mm-dd')+(LEVEL-1),'yyyy-mm-dd') as dt
  FROM DUAL
CONNECT BY LEVEL<=to_number(to_date('2017-12-30','yyyy-mm-dd')-to_date('2017-12-01','yyyy-mm-dd'))+1
)
,T2 as 
(
  select ? as date1,count(1) as count1 from ....
  --這裡的語句自己定了,我這只是對應下面的條件而已
)
SELECT m.dt,nvl(T2.count1,0) 
  FROM m LEFT JOIN T2 ON m.dt=T2.date1 order by m.dt;
這裡的LEVEL表示兩個時間之間的差值,比如:
SELECT to_char(ADD_MONTHS(to_date('2017-01-01','yyyy-mm-dd'),LEVEL-1),'yyyy-mm') as dt
FROM DUAL
CONNECT BY LEVEL<=MONTHS_BETWEEN(to_date('2017-12-30','yyyy-mm-dd'),to_date('2017-01-01','yyyy-mm-dd'))+1
其中LEVEL-1那裡,LEVEL從1開始往上遞增至12,也就迴圈了12次(不知道理解對不對,應該是的)

那麼以上內容基本就能滿足你的“連續的資料”了

4、補充

(1)、按年統計:

select ... from ...group by to_char(你的時間欄位,'yyyy')
(2)、按月統計
select ... from ...group by to_char(你的時間欄位,'yyyy-mm')
(3)、按日統計
select ... from ...group by to_char(你的時間欄位,'yyyy-mm-dd')
(4)、按季度統計
select ... from ...group by to_char(你的時間欄位,'q')

(5)、按周統計
select ... from ...group by to_char(你的時間欄位,'iw')

舉個例子:(按周統計)

select to_char(actualenddate,'iw') as day,nvl(count(1),0) as count1
 from   T1
 group by to_char(actualenddate,'iw') order by to_char(actualenddate,'iw')