2015-11-08 57 views
0

我們的數據庫將多個天的小時數存儲爲一個字符串(格式爲JSON,請參見下文)。我需要提取任何一天的時間。問題是JSON不保證有保證的順序的日子。如何將一串連接值拆分爲特定列

我試圖substrinstr這樣:

SUBSTR(hours_xltd, 
     INSTR(hours_xltd,'"MONDAY"', 1, 1)+1, 
     INSTR(hours_xltd,',',1,2) - INSTR(hours_xltd,',',1,1)-1) as Monday 

這給了我MONDAY":"0800-1800","F但我需要的是:

Monday 
0800-1800 

我需要同樣的事情Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday。這是所需的輸出(每天在它自己的列上,在我的例子中用管道表示);

monday | tuesday | wednesday | thursday | friday | saturday | sunday 
---------------------------------------------------------------------------------- 
0800-1800 | 0800-1800 | 0800-1800 | 0800-1800 | 0800-1800 | 0800-1800 | 0800-1800 

的樣本數據:

{ 
"default": { 
    "standard_hours": { 
     "TUESDAY":"0800-1800", 
     "SATURDAY":"0800-1400", 
     "WEDNESDAY":"0800-1800", 
     "THURSDAY":"0800-1800", 
     "SUNDAY":"", 
     "MONDAY":"0800-1800", 
     "FRIDAY":"0800-1800"} 
} 
}   

{ 
"default": { 
    "standard_hours": { 
     "MONDAY":"0800-1800", 
     "TUESDAY":"0800-1800", 
     "WEDNESDAY":"0800-1800", 
     "THURSDAY":"0800-1800", 
     "FRIDAY":"0800-1800", 
     "SATURDAY":"0800-1800", 
     "SUNDAY":"0800-1800"} 
    } 
} 

請幫我檢查代碼?我似乎無法弄清楚這一點。

+1

你會一直有2行7列輸出嗎?數據總是會在每週的每一天都有價值嗎?你總是希望星期一價值在第一列嗎?哦,你用的是什麼版本的Oracle? Oracle在12.1中內置了對JSON的支持。如果沒有,您是否使用第三方JSON包? –

+0

要回答你的一些問題,不,我將有多行,因爲數據範圍從1到很多。但是,我會一直有7欄輸出。不是所有的日子都會有價值(例如「星期六」:「」,「星期日」:「」)。我目前正在使用12.1。 –

回答

0

讓我們跳過一個關於將結構化數據以非結構化格式(如JSON)存儲起來並轉向解決方案的壞主意。

我們可以使用正則表達式提取日期名稱和小時數。正如我們所知,using regex in production code is a bad thing,所以當我們需要時,儘可能保持清晰是個好主意。

第一個公用表表達式提取DAY:HOUR字符串並將它們轉化爲結果集(在這個字符串拆分技巧中有幾個變體)。第二個CTE分隔DAY和HOUR字符串。主查詢使用聚合來轉動行。

with std as (select id 
        , regexp_substr(substr(json_str,31), '[^,]+', 1, level) as day_str 
       from t23 
       connect by level <= 7) 
    , hrs as (select distinct id 
         , regexp_substr(day_str, '([A-Z]+)') as d_str 
         , regexp_substr(day_str, '([0-9\-]+)') as h_str 
       from std) 
select id 
     , max(case when d_str = 'MONDAY' then h_str end) as monday 
     , max(case when d_str = 'TUESDAY' then h_str end) as tuesday 
     , max(case when d_str = 'WEDNESDAY' then h_str end) as wednesday 
     , max(case when d_str = 'THURSDAY' then h_str end) as thursday 
     , max(case when d_str = 'FRIDAY' then h_str end) as friday 
     , max(case when d_str = 'SATURDAY' then h_str end) as saturday 
     , max(case when d_str = 'SUNDAY' then h_str end) as sunday 
from hrs 
group by id 
order by id 
/

請注意,我需要一個ID列來使pivotimg工作。

18 ... 
19 order by id 
20/

     ID MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY SUNDAY 
---------- --------- --------- --------- --------- --------- --------- --------- 
     1 0800-1800 0800-1800 0800-1800 0800-1800 0800-1800 0800-1400 
     2 0800-1800 0800-1800 0800-1800 0800-1800 0800-1800 0800-1800 0800-1800 

SQL> 
+0

我開始玩這個遊戲,但由於缺乏可視化,我無法實現它。我打DAY的提取:下面HOUR: '選擇 ypid, hours_xltd, REGEXP_SUBSTR(hours_xltd, '([AZ] +)')作爲d_str, REGEXP_SUBSTR(hours_xltd,「([0-9 \ - ] +)')as h_str from listing_extract where ypid in('481973535','483796785','495850252','1452');' 使用我的表名和主鍵,你能幫我理解你的腳本? –

相關問題