0

エラールックアップとエラーの 2 つのテーブルがあります。errorlookup には、コードと説明の 2 つの列があります。コードの長さは 2 です。errors には id と errorcodes の 2 つの列があります。エラーコードの長さは 40 で、ID ごとに 20 個のエラー コードが格納されることを意味します。エラーコードの部分文字列によって id に関連付けられたすべての説明を表示し、エラールックアップ テーブルのコードと一致させる必要があります。errorlookup のサンプル データ:

コード:説明
   12:無効
   22:非アクティブ
   21:アクティブ

エラーのサンプル データ:

id:エラーコード
 1:1221
 2:2112
 3:1222

エラーが多すぎるため、LIKE は使用できません。errorcodes 列を長さ 2 の文字列に分割してから、errorlookup に結合したいと考えています。どうすればそれができますか?

4

3 に答える 3

2

テーブル構造を本当に変更できない場合は、別のアプローチがあります。

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-Fiddle

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
于 2012-05-05T00:10:16.917 に答える
1

最もクリーンな解決策は、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でも機能するはずです)

于 2012-05-04T23:31:01.317 に答える
0

で正しい軌道に乗っていると思いますLIKE。MySQL には正規表現によるマッチングを可能にする機能がありますRLIKE(Oracle に存在するかどうかはわかりません) 。このパターンは、「1213」のようなものが一致しないようにするために使用されます (たとえば、「21」)。errorlookup.codeerrors.errorcodes(..)*

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   |
+------+----------+------+
于 2012-05-04T19:03:25.627 に答える