国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【SQL開發(fā)實戰(zhàn)技巧】系列(三十六):數(shù)倉報表場景?整理垃圾數(shù)據(jù):查找數(shù)據(jù)的連續(xù)性時間和重疊時間的關(guān)系,初始化開始結(jié)束時間

這篇具有很好參考價值的文章主要介紹了【SQL開發(fā)實戰(zhàn)技巧】系列(三十六):數(shù)倉報表場景?整理垃圾數(shù)據(jù):查找數(shù)據(jù)的連續(xù)性時間和重疊時間的關(guān)系,初始化開始結(jié)束時間。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

系列文章目錄

【SQL開發(fā)實戰(zhàn)技巧】系列(一):關(guān)于SQL不得不說的那些事
【SQL開發(fā)實戰(zhàn)技巧】系列(二):簡單單表查詢
【SQL開發(fā)實戰(zhàn)技巧】系列(三):SQL排序的那些事
【SQL開發(fā)實戰(zhàn)技巧】系列(四):從執(zhí)行計劃討論UNION ALL與空字符串&UNION與OR的使用注意事項
【SQL開發(fā)實戰(zhàn)技巧】系列(五):從執(zhí)行計劃看IN、EXISTS 和 INNER JOIN效率,我們要分場景不要死記網(wǎng)上結(jié)論
【SQL開發(fā)實戰(zhàn)技巧】系列(六):從執(zhí)行計劃看NOT IN、NOT EXISTS 和 LEFT JOIN效率,記住內(nèi)外關(guān)聯(lián)條件不要亂放
【SQL開發(fā)實戰(zhàn)技巧】系列(七):從有重復數(shù)據(jù)前提下如何比較出兩個表中的差異數(shù)據(jù)及對應條數(shù)聊起
【SQL開發(fā)實戰(zhàn)技巧】系列(八):聊聊如何插入數(shù)據(jù)時比約束更靈活的限制數(shù)據(jù)插入以及怎么一個insert語句同時插入多張表
【SQL開發(fā)實戰(zhàn)技巧】系列(九):一個update誤把其他列數(shù)據(jù)更新成空了?Merge改寫update!給你五種刪除重復數(shù)據(jù)的寫法!
【SQL開發(fā)實戰(zhàn)技巧】系列(十):從拆分字符串、替換字符串以及統(tǒng)計字符串出現(xiàn)次數(shù)說起
【SQL開發(fā)實戰(zhàn)技巧】系列(十一):拿幾個案例講講translate|regexp_replace|listagg|wmsys.wm_concat|substr|regexp_substr常用函數(shù)
【SQL開發(fā)實戰(zhàn)技巧】系列(十二):三問(如何對字符串字母去重后按字母順序排列字符串?如何識別哪些字符串中包含數(shù)字?如何將分隔數(shù)據(jù)轉(zhuǎn)換為多值IN列表?)
【SQL開發(fā)實戰(zhàn)技巧】系列(十三):討論一下常用聚集函數(shù)&通過執(zhí)行計劃看sum()over()對員工工資進行累加
【SQL開發(fā)實戰(zhàn)技巧】系列(十四):計算消費后的余額&計算銀行流水累計和&計算各部門工資排名前三位的員工
【SQL開發(fā)實戰(zhàn)技巧】系列(十五):查找最值所在行數(shù)據(jù)信息及快速計算總和百之max/min() keep() over()、fisrt_value、last_value、ratio_to_report
【SQL開發(fā)實戰(zhàn)技巧】系列(十六):數(shù)據(jù)倉庫中時間類型操作(初級)日、月、年、時、分、秒之差及時間間隔計算
【SQL開發(fā)實戰(zhàn)技巧】系列(十七):數(shù)據(jù)倉庫中時間類型操作(初級)確定兩個日期之間的工作天數(shù)、計算—年中周內(nèi)各日期出現(xiàn)次數(shù)、確定當前記錄和下一條記錄之間相差的天數(shù)
【SQL開發(fā)實戰(zhàn)技巧】系列(十八):數(shù)據(jù)倉庫中時間類型操作(進階)INTERVAL、EXTRACT以及如何確定一年是否為閏年及周的計算
【SQL開發(fā)實戰(zhàn)技巧】系列(十九):數(shù)據(jù)倉庫中時間類型操作(進階)如何一個SQL打印當月或一年的日歷?如何確定某月內(nèi)第一個和最后—個周內(nèi)某天的日期?
【SQL開發(fā)實戰(zhàn)技巧】系列(二十):數(shù)據(jù)倉庫中時間類型操作(進階)獲取季度開始結(jié)束時間以及如何統(tǒng)計非連續(xù)性時間的數(shù)據(jù)
【SQL開發(fā)實戰(zhàn)技巧】系列(二十一):數(shù)據(jù)倉庫中時間類型操作(進階)識別重疊的日期范圍,按指定10分鐘時間間隔匯總數(shù)據(jù)
【SQL開發(fā)實戰(zhàn)技巧】系列(二十二):數(shù)倉報表場景? 從分析函數(shù)效率一定快嗎聊一聊結(jié)果集分頁和隔行抽樣實現(xiàn)方式
【SQL開發(fā)實戰(zhàn)技巧】系列(二十三):數(shù)倉報表場景? 如何對數(shù)據(jù)排列組合去重以及通過如何找到包含最大值和最小值的記錄這個問題再次用執(zhí)行計劃給你證明分析函數(shù)性能不一定高
【SQL開發(fā)實戰(zhàn)技巧】系列(二十四):數(shù)倉報表場景?通過案例執(zhí)行計劃詳解”行轉(zhuǎn)列”,”列轉(zhuǎn)行”是如何實現(xiàn)的
【SQL開發(fā)實戰(zhàn)技巧】系列(二十五):數(shù)倉報表場景?結(jié)果集中的重復數(shù)據(jù)只顯示一次以及計算部門薪資差異高效的寫法以及如何對數(shù)據(jù)進行快速分組
【SQL開發(fā)實戰(zhàn)技巧】系列(二十六):數(shù)倉報表場景?聊聊ROLLUP、UNION ALL是如何分別做分組合計的以及如何識別哪些行是做匯總的結(jié)果行
【SQL開發(fā)實戰(zhàn)技巧】系列(二十七):數(shù)倉報表場景?通過對移動范圍進行聚集來詳解分析函數(shù)開窗原理以及如何一個SQL打印九九乘法表
【SQL開發(fā)實戰(zhàn)技巧】系列(二十八):數(shù)倉報表場景?人員分布問題以及不同組(分區(qū))同時聚集如何實現(xiàn)
【SQL開發(fā)實戰(zhàn)技巧】系列(二十九):數(shù)倉報表場景?簡單的樹形(分層)查詢以及如何確定根節(jié)點、分支節(jié)點和葉子節(jié)點
【SQL開發(fā)實戰(zhàn)技巧】系列(三十):數(shù)倉報表場景?樹形(分層)查詢?nèi)绾闻判??以及如何在樹形查詢中正確的使用where條件
【SQL開發(fā)實戰(zhàn)技巧】系列(三十一):數(shù)倉報表場景?分層查詢?nèi)绾沃徊樵儤湫谓Y(jié)構(gòu)某一個分支?如何剪掉一個分支?
【SQL開發(fā)實戰(zhàn)技巧】系列(三十二):數(shù)倉報表場景?對表中某個字段內(nèi)的值去重
【SQL開發(fā)實戰(zhàn)技巧】系列(三十三):數(shù)倉報表場景?從不固定位置提取字符串的元素以及搜索滿足字母在前數(shù)字在后等條件的數(shù)據(jù)
【SQL開發(fā)實戰(zhàn)技巧】系列(三十四):數(shù)倉報表場景?如何對數(shù)據(jù)分級并行轉(zhuǎn)為列
【SQL開發(fā)實戰(zhàn)技巧】系列(三十五):數(shù)倉報表場景?根據(jù)條件返回不同列的數(shù)據(jù)以及Left /Full Join注意事項
【SQL開發(fā)實戰(zhàn)技巧】系列(三十六):數(shù)倉報表場景?整理垃圾數(shù)據(jù):查找數(shù)據(jù)的連續(xù)性時間和重疊時間的關(guān)系,初始化開始結(jié)束時間



前言

本篇文章講解的主要內(nèi)容是:從整理人員簽到信息記錄表的垃圾數(shù)據(jù)來再次體會一下隱藏數(shù)據(jù)列信息以及查找數(shù)據(jù)的連續(xù)性時間和重疊時間的實戰(zhàn)案例
【SQL開發(fā)實戰(zhàn)技巧】這一系列博主當作復習舊知識來進行寫作,畢竟SQL開發(fā)在數(shù)據(jù)分析場景非常重要且基礎(chǔ),面試也會經(jīng)常問SQL開發(fā)和調(diào)優(yōu)經(jīng)驗,相信當我寫完這一系列文章,也能再有所收獲,未來面對SQL面試也能游刃有余~。


一、整理垃圾數(shù)據(jù):查找數(shù)據(jù)的連續(xù)性時間和重疊時間的關(guān)系,初始化開始結(jié)束時間

現(xiàn)在有下面一堆臟數(shù)據(jù),是人員簽到信息記錄表,如下:

CREATE OR REPLACE VIEW people(人員編號,開始時間,結(jié)束時間,類型,數(shù)值id)AS
SELECT 11, to_date('201305', 'yyyymm'), to_date('201308', 'yyyymm'), 1, 1
  FROM dual
UNION ALL
SELECT 11, to_date('201307', 'yyyymm'), NULL, 1, 2
  FROM dual
UNION ALL
SELECT 11, to_date('201301', 'yyyymm'), NULL, -1, 3
  FROM dual
UNION ALL
SELECT 11, to_date('201312', 'yyyymm'), NULL, 1, 4
  FROM dual
UNION ALL
SELECT 22, to_date('201305', 'yyyymm'), to_date('201306', 'yyyymm'), 1, 1
  FROM dual
UNION ALL
SELECT 22, to_date('201308', 'yyyymm'), to_date('201309', 'yyyymm'), 1, 2
  FROM dual
UNION ALL
SELECT 22, to_date('201312', 'yyyymm'), to_date('201312', 'yyyymm'), -1, 3
  FROM dual
UNION ALL
SELECT 22, to_date('201403', 'yyyymm'), NULL, 1, 4
  FROM dual
UNION ALL
SELECT 22, to_date('201405', 'yyyymm'), NULL, -1, 4
  FROM dual
UNION ALL
SELECT 33, to_date('201305', 'yyyymm'), to_date('201305', 'yyyymm'), 1, 1
  FROM dual
UNION ALL
SELECT 33, to_date('201307', 'yyyymm'), to_date('201307', 'yyyymm'), 1, 2
  from dual
union all
SELECT 33, to_date('201310', 'yyyymm'), NULL, -1, 3
  FROM dual
UNION ALL
SELECT 33, to_date('201312', 'yyyymm'), NULL, 1, 4
  FROM dual;
SQL> select *from people;

      人員編號 開始時間    結(jié)束時間            類型       數(shù)值ID
---------- ----------- ----------- ---------- ----------
        11 2013-5-1    2013-8-1             1          1
        11 2013-7-1                         1          2
        11 2013-1-1                        -1          3
        11 2013-12-1                        1          4
        22 2013-5-1    2013-6-1             1          1
        22 2013-8-1    2013-9-1             1          2
        22 2013-12-1   2013-12-1           -1          3
        22 2014-3-1                         1          4
        22 2014-5-1                        -1          4
        33 2013-5-1    2013-5-1             1          1
        33 2013-7-1    2013-7-1             1          2
        33 2013-10-1                       -1          3
        33 2013-12-1                        1          4

13 rows selected

上面的數(shù)據(jù)是雜亂的,要求清洗上面數(shù)據(jù),得到如下數(shù)據(jù):

人員編號 區(qū)間
---------- ----------- 
11	201312--NULL
22	201305--201306
22	201308--201309
22	201403--201404
33	201305--201305
33	201307--201307
33	201312--NULL

由于上面數(shù)據(jù)質(zhì)量不高,現(xiàn)在提出數(shù)據(jù)清洗規(guī)則需求如下:
1、當類型為"-1"時,數(shù)據(jù)丟棄。
2、當類型為"-1",且其前一行"結(jié)束時間"為空值時,"開始時間-1"當作其前一行的結(jié)束時間。
3、如果后面的時間比前面的時間早,則覆蓋前面的時間,不能覆蓋的時間要保留。
4、時段重疊的要合并為一行。
數(shù)據(jù)亂,需求也就復雜。
首先要取出對應的數(shù)據(jù),剛開始寫語句時可能不知道從何下手,沒關(guān)系,我們一步步分析:

select 人員編號,
with t as (
select 人員編號,
       開始時間,
       min(開始時間) over(partition by 人員編號 order by 數(shù)值id rows between 1 following and unbounded following) as tmp開始時間,
       min(case
             when 類型 = -1 then
              add_months(開始時間, -1)
             else
              開始時間
           end) over(partition by 人員編號 order by 數(shù)值id rows between 1 following and unbounded following) as tmp_min開始時間,
       coalesce(min(case
                      when 類型 = -1 then
                       add_months(開始時間, -1)
                      else
                       開始時間
                    end)
                over(partition by 人員編號 order by 數(shù)值id rows between 1
                     following and unbounded following),
                開始時間 + 1) as min_開始時間,
       結(jié)束時間 as tmp_結(jié)束時間,
       case
         when 結(jié)束時間 is null and
              (lead(類型) over(partition by 人員編號 order by 數(shù)值id)) = -1 then
          add_months(lead(開始時間) over(partition by 人員編號 order by 數(shù)值id),
                     -1)
         else
          結(jié)束時間
       end as 結(jié)束時間,
       類型,
       數(shù)值ID,
       max(數(shù)值id) over(partition by 人員編號) as max_id
  from people
)
select * from t;

      人員編號 開始時間    TMP開始時間 TMP_MIN開始時間 MIN_開始時間 TMP_結(jié)束時間 結(jié)束時間            類型       數(shù)值ID     MAX_ID
---------- ----------- ----------- ----------- ----------- ----------- ----------- ---------- ---------- ----------
        11 2013-5-1    2013-1-1    2012-12-1   2012-12-1   2013-8-1    2013-8-1             1          1          4
        11 2013-7-1    2013-1-1    2012-12-1   2012-12-1               2012-12-1            1          2          4
        11 2013-1-1    2013-12-1   2013-12-1   2013-12-1                                   -1          3          4
        11 2013-12-1                           2013-12-2                                    1          4          4
        22 2013-5-1    2013-8-1    2013-8-1    2013-8-1    2013-6-1    2013-6-1             1          1          4
        22 2013-8-1    2013-12-1   2013-11-1   2013-11-1   2013-9-1    2013-9-1             1          2          4
        22 2013-12-1   2014-3-1    2014-3-1    2014-3-1    2013-12-1   2013-12-1           -1          3          4
        22 2014-3-1    2014-5-1    2014-4-1    2014-4-1                2014-4-1             1          4          4
        22 2014-5-1                            2014-5-2                                    -1          4          4
        33 2013-5-1    2013-7-1    2013-7-1    2013-7-1    2013-5-1    2013-5-1             1          1          4
        33 2013-7-1    2013-10-1   2013-9-1    2013-9-1    2013-7-1    2013-7-1             1          2          4
        33 2013-10-1   2013-12-1   2013-12-1   2013-12-1                                   -1          3          4
        33 2013-12-1                           2013-12-2                                    1          4          4

13 rows selected

上面標識了"開始時間"(見第三條)與"結(jié)束時間"(見第二條)分別處理的過程。

with t as (
select 人員編號,
       開始時間,
       min(開始時間) over(partition by 人員編號 order by 數(shù)值id rows between 1 following and unbounded following) as tmp開始時間,
       min(case
             when 類型 = -1 then
              add_months(開始時間, -1)
             else
              開始時間
           end) over(partition by 人員編號 order by 數(shù)值id rows between 1 following and unbounded following) as tmp_min開始時間,
       coalesce(min(case
                      when 類型 = -1 then
                       add_months(開始時間, -1)
                      else
                       開始時間
                    end)
                over(partition by 人員編號 order by 數(shù)值id rows between 1
                     following and unbounded following),
                開始時間 + 1) as min_開始時間,--當前人員的最小日期,覆蓋用
       結(jié)束時間 as tmp_結(jié)束時間,
       case
         when 結(jié)束時間 is null and
              (lead(類型) over(partition by 人員編號 order by 數(shù)值id)) = -1 then
          add_months(lead(開始時間) over(partition by 人員編號 order by 數(shù)值id),
                     -1)
         else
          結(jié)束時間
       end as 結(jié)束時間,
       類型,
       數(shù)值ID,
       max(數(shù)值id) over(partition by 人員編號) as max_id
  from people
)
select 人員編號,
       開始時間,
       min_開始時間,
       結(jié)束時間,
       類型,
       數(shù)值ID,
       max_id,
       case--生成區(qū)間是否重疊的標識,合并時段時用
         when (lag(結(jié)束時間) over(partition by 人員編號 order by 數(shù)值id)) <
              add_months(開始時間, -1) then
          1
         when (lag(類型) over(partition by 人員編號 order by 數(shù)值id)) = 1 then
          null
         else
          1
       end as so
  from t;
      人員編號 開始時間    MIN_開始時間 結(jié)束時間            類型       數(shù)值ID     MAX_ID         SO
---------- ----------- ----------- ----------- ---------- ---------- ---------- ----------
        11 2013-5-1    2012-12-1   2013-8-1             1          1          4          1
        11 2013-7-1    2012-12-1   2012-12-1            1          2          4 
        11 2013-1-1    2013-12-1                       -1          3          4 
        11 2013-12-1   2013-12-2                        1          4          4          1
        22 2013-5-1    2013-8-1    2013-6-1             1          1          4          1
        22 2013-8-1    2013-11-1   2013-9-1             1          2          4          1
        22 2013-12-1   2014-3-1    2013-12-1           -1          3          4          1
        22 2014-3-1    2014-4-1    2014-4-1             1          4          4          1
        22 2014-5-1    2014-5-2                        -1          4          4 
        33 2013-5-1    2013-7-1    2013-5-1             1          1          4          1
        33 2013-7-1    2013-9-1    2013-7-1             1          2          4          1
        33 2013-10-1   2013-12-1                       -1          3          4          1
        33 2013-12-1   2013-12-2                        1          4          4          1

13 rows selected

生成分組標識,如果后錄入的數(shù)據(jù)開始時間更早,就說明前面錄入的是無用的數(shù)據(jù),要丟棄,如果范圍重疊,就修正前面的結(jié)束時間。

with t as (
select 人員編號,
       開始時間,
       min(開始時間) over(partition by 人員編號 order by 數(shù)值id rows between 1 following and unbounded following) as tmp開始時間,
       min(case
             when 類型 = -1 then
              add_months(開始時間, -1)
             else
              開始時間
           end) over(partition by 人員編號 order by 數(shù)值id rows between 1 following and unbounded following) as tmp_min開始時間,
       coalesce(min(case
                      when 類型 = -1 then
                       add_months(開始時間, -1)
                      else
                       開始時間
                    end)
                over(partition by 人員編號 order by 數(shù)值id rows between 1
                     following and unbounded following),
                開始時間 + 1) as min_開始時間,--當前人員的最小日期,覆蓋用
       結(jié)束時間 as tmp_結(jié)束時間,
       case
         when 結(jié)束時間 is null and
              (lead(類型) over(partition by 人員編號 order by 數(shù)值id)) = -1 then
          add_months(lead(開始時間) over(partition by 人員編號 order by 數(shù)值id),
                     -1)
         else
          結(jié)束時間
       end as 結(jié)束時間,
       類型,
       數(shù)值ID,
       max(數(shù)值id) over(partition by 人員編號) as max_id
  from people
),
t1 as (
select 人員編號,
       開始時間,
       min_開始時間,
       結(jié)束時間,
       類型,
       數(shù)值ID,
       max_id,
       case--生成區(qū)間是否重疊的標識,合并時段時用
         when (lag(結(jié)束時間) over(partition by 人員編號 order by 數(shù)值id)) <
              add_months(開始時間, -1) then
          1
         when (lag(類型) over(partition by 人員編號 order by 數(shù)值id)) = 1 then
          null
         else
          1
       end as so
  from t)
  select 人員編號,
         數(shù)值ID,
         max_id,
         類型,
         sum(so) over(partition by 人員編號 order by 數(shù)值id) as so,/*累加標識,生成分組合并依據(jù)*/
         開始時間,
         min_開始時間,
         case/*根據(jù)最前面生成的時間覆蓋對應的時段*/
           when min_開始時間 < 結(jié)束時間 and min_開始時間 >= 開始時間 then
            min_開始時間
           else
            結(jié)束時間
         end as 結(jié)束時間
    from t1
   where 類型 = 1
   /*如果開始時間比這還小,就丟棄吧*/
     and 開始時間 <= min_開始時間;
  
      人員編號       數(shù)值ID     MAX_ID         類型         SO 開始時間    MIN_開始時間 結(jié)束時間
---------- ---------- ---------- ---------- ---------- ----------- ----------- -----------
        11          4          4          1          1 2013-12-1   2013-12-2   
        22          1          4          1          1 2013-5-1    2013-8-1    2013-6-1
        22          2          4          1          2 2013-8-1    2013-11-1   2013-9-1
        22          4          4          1          3 2014-3-1    2014-4-1    2014-4-1
        33          1          4          1          1 2013-5-1    2013-7-1    2013-5-1
        33          2          4          1          2 2013-7-1    2013-9-1    2013-7-1
        33          4          4          1          3 2013-12-1   2013-12-2   

7 rows selected

合并數(shù)據(jù),語句如下:

/*人員編號 NUMBER Y 
開始時間 DATE   Y 
結(jié)束時間 DATE   Y 
類型 NUMBER Y   
數(shù)值ID NUMBER Y 
1、當類型為"-l"時,數(shù)據(jù)丟棄。
2、當類型為"-1",且其前一行"結(jié)束時間"為空值時,"開始時間-1"當作其前一行的結(jié)束時間。
3、如果后面的時間比前面的時間早,則覆蓋前面的時間,不能覆蓋的時間要保留。
5、時段重疊的要合并為一行。

*/


with t as (
select 人員編號,
       開始時間,
       min(開始時間) over(partition by 人員編號 order by 數(shù)值id rows between 1 following and unbounded following) as tmp開始時間,
       min(case
             when 類型 = -1 then
              add_months(開始時間, -1)
             else
              開始時間
           end) over(partition by 人員編號 order by 數(shù)值id rows between 1 following and unbounded following) as tmp_min開始時間,
       coalesce(min(case
                      when 類型 = -1 then
                       add_months(開始時間, -1)
                      else
                       開始時間
                    end)
                over(partition by 人員編號 order by 數(shù)值id rows between 1
                     following and unbounded following),
                開始時間 + 1) as min_開始時間,--當前人員的最小日期,覆蓋用
       結(jié)束時間 as tmp_結(jié)束時間,
       case
         when 結(jié)束時間 is null and
              (lead(類型) over(partition by 人員編號 order by 數(shù)值id)) = -1 then
          add_months(lead(開始時間) over(partition by 人員編號 order by 數(shù)值id),
                     -1)
         else
          結(jié)束時間
       end as 結(jié)束時間,
       類型,
       數(shù)值ID,
       max(數(shù)值id) over(partition by 人員編號) as max_id
  from people
),
t1 as (
select 人員編號,
       開始時間,
       min_開始時間,
       結(jié)束時間,
       類型,
       數(shù)值ID,
       max_id,
       case--生成區(qū)間是否重疊的標識,合并時段時用
         when (lag(結(jié)束時間) over(partition by 人員編號 order by 數(shù)值id)) <
              add_months(開始時間, -1) then
          1
         when (lag(類型) over(partition by 人員編號 order by 數(shù)值id)) = 1 then
          null
         else
          1
       end as so
  from t),
t2 as (
  select 人員編號,
         數(shù)值ID,
         max_id,
         類型,
         sum(so) over(partition by 人員編號 order by 數(shù)值id) as so,/*累加標識,生成分組合并依據(jù)*/
         開始時間,
         min_開始時間,
         case/*根據(jù)最前面生成的時間覆蓋對應的時段*/
           when min_開始時間 < 結(jié)束時間 and min_開始時間 >= 開始時間 then
            min_開始時間
           else
            結(jié)束時間
         end as 結(jié)束時間
    from t1
   where 類型 = 1
   /*如果開始時間比這還小,就丟棄吧*/
     and 開始時間 <= min_開始時間)
     select 人員編號,
            max_id,
            max(數(shù)值ID) as max_id2,
            sum(類型) as 類型,
            min(開始時間) keep(dense_rank first order by 數(shù)值id) as 開始時間,
            max(開始時間) keep(dense_rank last order by 數(shù)值id) as 結(jié)束時間
       from t2
      group by 人員編號, so, max_id;
      人員編號     MAX_ID    MAX_ID2         類型 開始時間    結(jié)束時間
---------- ---------- ---------- ---------- ----------- -----------
        11          4          4          1 2013-12-1   2013-12-1
        22          4          1          1 2013-5-1    2013-5-1
        22          4          2          1 2013-8-1    2013-8-1
        22          4          4          1 2014-3-1    2014-3-1
        33          4          1          1 2013-5-1    2013-5-1
        33          4          2          1 2013-7-1    2013-7-1
        33          4          4          1 2013-12-1   2013-12-1

7 rows selected

最后一步是過濾,語句如下:

with t as (
select 人員編號,
       開始時間,
       min(開始時間) over(partition by 人員編號 order by 數(shù)值id rows between 1 following and unbounded following) as tmp開始時間,
       min(case
             when 類型 = -1 then
              add_months(開始時間, -1)
             else
              開始時間
           end) over(partition by 人員編號 order by 數(shù)值id rows between 1 following and unbounded following) as tmp_min開始時間,
       coalesce(min(case
                      when 類型 = -1 then
                       add_months(開始時間, -1)
                      else
                       開始時間
                    end)
                over(partition by 人員編號 order by 數(shù)值id rows between 1
                     following and unbounded following),
                開始時間 + 1) as min_開始時間,--當前人員的最小日期,覆蓋用
       結(jié)束時間 as tmp_結(jié)束時間,
       case
         when 結(jié)束時間 is null and
              (lead(類型) over(partition by 人員編號 order by 數(shù)值id)) = -1 then
          add_months(lead(開始時間) over(partition by 人員編號 order by 數(shù)值id),
                     -1)
         else
          結(jié)束時間
       end as 結(jié)束時間,
       類型,
       數(shù)值ID,
       max(數(shù)值id) over(partition by 人員編號) as max_id
  from people
),
t1 as (
select 人員編號,
       開始時間,
       min_開始時間,
       結(jié)束時間,
       類型,
       數(shù)值ID,
       max_id,
       case--生成區(qū)間是否重疊的標識,合并時段時用
         when (lag(結(jié)束時間) over(partition by 人員編號 order by 數(shù)值id)) <
              add_months(開始時間, -1) then
          1
         when (lag(類型) over(partition by 人員編號 order by 數(shù)值id)) = 1 then
          null
         else
          1
       end as so
  from t),
t2 as (
  select 人員編號,
         數(shù)值ID,
         max_id,
         類型,
         sum(so) over(partition by 人員編號 order by 數(shù)值id) as so,/*累加標識,生成分組合并依據(jù)*/
         開始時間,
         min_開始時間,
         case/*根據(jù)最前面生成的時間覆蓋對應的時段*/
           when min_開始時間 < 結(jié)束時間 and min_開始時間 >= 開始時間 then
            min_開始時間
           else
            結(jié)束時間
         end as 結(jié)束時間
    from t1
   where 類型 = 1
   /*如果開始時間比這還小,就丟棄吧*/
     and 開始時間 <= min_開始時間),
     t3 as (
     select 人員編號,
            max_id,
            max(數(shù)值ID) as max_id2,
            sum(類型) as 類型,
            min(開始時間) keep(dense_rank first order by 數(shù)值id) as 開始時間,
            max(開始時間) keep(dense_rank last order by 數(shù)值id) as 結(jié)束時間
       from t2
      group by 人員編號, so, max_id)
      select 人員編號,to_char(開始時間,'yyyymm')||'--'||to_char(結(jié)束時間,'yyyymm') as str
      from t3
      where (max_id=max_id2 or 開始時間<=結(jié)束時間)
      and 類型>-1;
            人員編號 STR
---------- --------------------------------------------------------------------------------
        11 201312--201312
        22 201305--201305
        22 201308--201308
        22 201403--201403
        33 201305--201305
        33 201307--201307
        33 201312--201312

7 rows selected

到這一步就可以了。整理數(shù)據(jù)是最考驗耐心的工作,特別是需求還不確定的時候。


總結(jié)

本篇文章講解的主要內(nèi)容是:從整理人員簽到信息記錄表的垃圾數(shù)據(jù)來再次體會一下隱藏數(shù)據(jù)列信息以及查找數(shù)據(jù)的連續(xù)性時間和重疊時間的實戰(zhàn)案例文章來源地址http://www.zghlxwxcb.cn/news/detail-438058.html

到了這里,關(guān)于【SQL開發(fā)實戰(zhàn)技巧】系列(三十六):數(shù)倉報表場景?整理垃圾數(shù)據(jù):查找數(shù)據(jù)的連續(xù)性時間和重疊時間的關(guān)系,初始化開始結(jié)束時間的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包