簡體   English   中英

如何對子字符串進行子字符串化並與另一個表聯接

[英]How to substring and join with another table with the substring result

我有2表:errorlookup和錯誤。 errorlookup有2列:代碼和描述。 這些代碼的長度為2。錯誤有2列ID和錯誤代碼。 錯誤代碼的長度為40,這意味着它們為每個id存儲20個錯誤代碼。 我需要通過錯誤代碼的子字符串顯示所有與id相關的描述,並與errorlookup表中的代碼匹配。 錯誤查找的樣本數據:

codes:description
   12:Invalid
   22:Inactive
   21:active

錯誤的樣本數據:

id:errorcodes
 1:1221
 2:2112
 3:1222

我不能使用LIKE,因為它會導致太多錯誤。 我希望將errorcodes列分解為長度為2的字符串,然后與errorlookup合並。 如何做呢?

如果您真的無法更改表結構,則可以采用以下另一種方法:

創建輔助numbers表:

CREATE TABLE numbers
( i INT NOT NULL 
, PRIMARY KEY (i)
) ;

INSERT INTO numbers VALUES
( 1 ) ;   
INSERT INTO numbers VALUES
( 2 ) ;
--- ...
INSERT INTO numbers VALUES
( 100 ) ;

然后,您可以使用以下代碼:

SELECT err.id
     , err.errorcodes
     , num.i
     , look.codes
    , look.descriptionid
FROM
    ( SELECT i, 2*i-1 AS pos      --- odd numbers
      FROM numbers
      WHERE i <= 20               --- 20 pairs
    ) num 
  CROSS JOIN 
    errors  err
  JOIN 
    errorlookup  look
      ON look.codes = SUBSTR(err.errorcodes, pos, 2)
ORDER BY 
    err.errorcodes
  , num.i ;

在以下位置進行測試: SQL小提琴

ID  ERRORCODES  I   CODES  DESCRIPTIONID
1   1221        1   12     Invalid
1   1221        2   21     Active
3   1222        1   12     Invalid
3   1222        2   22     Inactive
2   2112        1   21     Active
2   2112        2   12     Invalid

我認為最干凈的解決方案是使用PL / SQL函數“標准化”您的errocodes表。 這樣,您可以保留當前(損壞的)表設計,但仍然可以像對其進行規范化一樣訪問其內容。

create type error_code_type as object (id integer, code varchar(2))
/

create or replace type error_table as table of error_code_type
/

create or replace function unnest_errors
   return error_table pipelined
is  
  codes_l integer;
  i       integer;
  one_row error_code_type := error_code_type(null, null);
begin
  for err_rec in (select id, errorcodes from errors) loop
    codes_l := length(err_rec.errorcodes);
    i := 1;
    while i < codes_l loop
        one_row.id   := err_rec.id;
        one_row.code := substr(err_rec.errorcodes, i, 2);
        pipe row (one_row);
        i := i + 2;
    end loop;
  end loop;
end;
/

現在,使用此功能,您可以執行以下操作:

select er.id, er.code, el.description
from table(unnest_errors) er
  join errorlookup el on el.codes = er.code;

您還可以基於該函數創建一個視圖,以使語句更易於閱讀:

create or replace view normalized_errorcodes 
as
select *
from table(unnest_errors);

然后,您可以簡單地在實際語句中引用視圖。

(我在11.2上進行了測試,但我相信它也應該在10.x上也可以使用)

我認為您在LIKE的正確。 MySQL具有RLIKE函數,該函數允許通過正則表達式進行匹配(我不知道它是否存在於Oracle中。)您可以使用errorlookup.code作為與errors.errorcodes進行匹配的模式。 (..)*模式用於防止匹配“ 1213”之類的內容,例如“ 21”。

SELECT *
FROM error
JOIN errorlookup
WHERE errorcodes RLIKE CONCAT('^(..)*',code)
ORDER BY id;

+------+----------+------+
| id   | errorcode| code |
+------+----------+------+
|    1 | 11       | 11   |
|    2 | 1121     | 11   |
|    2 | 1121     | 21   |
|    3 | 21313245 | 21   |
|    3 | 21313245 | 31   |
|    3 | 21313245 | 32   |
|    4 | 21       | 21   |
+------+----------+------+

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM