![](/img/trans.png)
[英]How can I create a View in Oracle with a String column whose content is aggregated from numeric values of related entities?
[英]How would I extract a substring from a string and create a new numeric column in Oracle SQL
我有一列 (DFI6),其中的值看起來像這樣,我有數百萬個。 我試圖用 COD (COD1,COD2....COD5) 值創建一個新的 NUMERIC 列。
表格的圖像這是它應該看起來的樣子,我有第一列,我正在嘗試創建 5 個新列
現在我正處於開始階段,我正在嘗試創建單獨的查詢並對其進行測試,而不是一個大的嵌套查詢。
有時 COD5 的值是字面上的“無”。 我查詢提取 COD5
select DFI6, (case when DFI6 like '%COD5%' THEN (case when REGEXP_LIKE(SUBSTR(SUBSTR(DFI6, INSTR(DFI6,'COD5=')),6),'[az]') then '-1' else (nvl(SUBSTR(SUBSTR(DFI6, INSTR(DFI6,'COD5=')),6),'-1')) end) else '-1' end)+0 --note: I added zero to turn the column into numeric as COD5 from myTable where updated_date>sysdate-300 and DFI6 is not null
提取 COD4 的查詢是:
select DFI6, (case when DFI6 like '%COD4%' THEN (case when REGEXP_LIKE(SUBSTR(SUBSTR(DFI6, INSTR(DFI6,'COD4=')),6),'[az]') then '-1' else SUBSTR(SUBSTR(DFI6, INSTR(DFI6, 'COD3'), INSTR(DFI6, '|COD4') - INSTR(DFI6, 'COD3')),6) end) else '-1' end)+0 --note: I added zero to turn the column into numeric as COD4 from myTable where updated_date>sysdate-30 and DFI6 is not null
問題:
我正在使用 SQL navigator6.2.1 oracle DB 版本 [19.16.0.0.0],一些新功能不適用於我的版本。 我是 SQL 的新手,非常感謝任何幫助。 謝謝
試試這個——只使用 CASE 表達式和 SubStr() function:
WITH -- Sample data
tbl AS
(
Select 'COD1=01YTEFG|COD2=22|COD3=33|COD4=21|COD5=22' "DFI6" From Dual Union All
Select 'COD1=02YTEFG|COD2=25|COD3=37|COD4=27|COD5=28' "DFI6" From Dual Union All
Select 'COD1=01YTEFG|COD2=22|COD3=33|COD4=21|COD5=22' "DFI6" From Dual Union All
Select 'COD1=02YTEFG|COD2=25|COD3=37|COD4=27' "DFI6" From Dual Union All -- NO COD5
Select 'COD1=02YTEFG|COD2=253|COD3=37|COD4=27' "DFI6" From Dual Union All -- NO COD5 AND COD2 HAS THREE NUMBERS
Select 'COD1=None|COD2=22|COD3=33|COD4=21|COD5=22' "DFI6" From Dual Union All -- COD1 = None
Select 'COD1=02YTEFG|COD5=28' "DFI6" From Dual Union All -- NO CODES 2, 3 AND 4
Select 'COD1=01YTEFG|COD2=22|COD3=33|COD4=21|COD5=22' "DFI6" From Dual Union All
Select 'COD1=02YTEFG|COD2=25|COD3=37|COD4=27|COD5=Nothing' "DFI6" From Dual
)
--
-- Main SQL
SELECT
DFI6,
CASE
WHEN INSTR(DFI6, 'COD1=') = 0 OR -- element is not here OR
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD1=') + 5, 1)) = 0 -- first char after 'COD1=' is not numeric
THEN -1
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD1=') + 7, 1)) > 0 AND -- third and
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD1=') + 6, 1)) > 0 AND -- second and
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD1=') + 5, 1)) > 0 -- first char after 'COD1=' are all numerics
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD1=') + 5, 3)) -- take all three
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD1=') + 6, 1)) > 0 AND -- second and
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD1=') + 5, 1)) > 0 -- first char after 'COD1=' are both numerics
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD1=') + 5, 2)) -- take them both
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD1=') + 5, 1)) > 0 -- just 1 numeric char after 'COD1='
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD1=') + 5, 1)) -- take it
ELSE -1 END "COD1", -- ELSE -1
-- ---------------------------------------------
CASE
WHEN INSTR(DFI6, 'COD2=') = 0 OR
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD2=') + 5, 1)) = 0
THEN -1
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD2=') + 7, 1)) > 0 AND
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD2=') + 6, 1)) > 0 AND
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD2=') + 5, 1)) > 0
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD2=') + 5, 3))
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD2=') + 6, 1)) > 0 AND
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD2=') + 5, 1)) > 0
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD2=') + 5, 2))
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD2=') + 5, 1)) > 0
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD2=') + 5, 1))
ELSE -1 END "COD2",
-- ---------------------------------------------
CASE
WHEN INSTR(DFI6, 'COD3=') = 0 OR
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD3=') + 5, 1)) = 0
THEN -1
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD3=') + 7, 1)) > 0 AND
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD3=') + 6, 1)) > 0 AND
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD3=') + 5, 1)) > 0
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD3=') + 5, 3))
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD3=') + 6, 1)) > 0 AND
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD3=') + 5, 1)) > 0
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD3=') + 5, 2))
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD3=') + 5, 1)) > 0
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD3=') + 5, 1))
ELSE -1 END "COD3",
-- ---------------------------------------------
CASE
WHEN INSTR(DFI6, 'COD4=') = 0 OR
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD4=') + 5, 1)) = 0
THEN -1
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD4=') + 7, 1)) > 0 AND
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD4=') + 6, 1)) > 0 AND
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD4=') + 5, 1)) > 0
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD4=') + 5, 3))
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD4=') + 6, 1)) > 0 AND
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD4=') + 5, 1)) > 0
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD4=') + 5, 2))
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD4=') + 5, 1)) > 0
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD4=') + 5, 1))
ELSE -1 END "COD4",
-- ---------------------------------------------
CASE
WHEN INSTR(DFI6, 'COD5=') = 0 OR
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD5=') + 5, 1)) = 0
THEN -1
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD5=') + 7, 1)) > 0 AND
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD5=') + 6, 1)) > 0 AND
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD5=') + 5, 1)) > 0
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD5=') + 5, 3))
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD5=') + 6, 1)) > 0 AND
INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD5=') + 5, 1)) > 0
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD5=') + 5, 2))
--
WHEN INSTR('0123456789', SubStr(DFI6, InStr(DFI6, 'COD5=') + 5, 1)) > 0
THEN To_Number(SubStr(DFI6, InStr(DFI6, 'COD5=') + 5, 1))
ELSE -1 END "COD5"
FROM tbl
--
/* R e s u l t :
DFI6 COD1 COD2 COD3 COD4 COD5
------------------------------------------------- ---------- ---------- ---------- ---------- ----------
COD1=01YTEFG|COD2=22|COD3=33|COD4=21|COD5=22 1 22 33 21 22
COD1=02YTEFG|COD2=25|COD3=37|COD4=27|COD5=28 2 25 37 27 28
COD1=01YTEFG|COD2=22|COD3=33|COD4=21|COD5=22 1 22 33 21 22
COD1=02YTEFG|COD2=25|COD3=37|COD4=27 2 25 37 27 -1
COD1=02YTEFG|COD2=253|COD3=37|COD4=27 2 253 37 27 -1
COD1=None|COD2=22|COD3=33|COD4=21|COD5=22 -1 22 33 21 22
COD1=02YTEFG|COD5=28 2 -1 -1 -1 28
COD1=01YTEFG|COD2=22|COD3=33|COD4=21|COD5=22 1 22 33 21 22
COD1=02YTEFG|COD2=25|COD3=37|COD4=27|COD5=Nothing 2 25 37 27 -1
*/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.