Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何使用子字符串结果与另一个表进行子字符串和联接_Sql_Oracle_Oracle10g - Fatal编程技术网

Sql 如何使用子字符串结果与另一个表进行子字符串和联接

Sql 如何使用子字符串结果与另一个表进行子字符串和联接,sql,oracle,oracle10g,Sql,Oracle,Oracle10g,我有两个表:errorlookup和errors。 errorlookup有两列:代码和说明。 代码长度为2。 errors有两列id和errorcodes。 错误代码的长度为40,这意味着它们为每个id存储20个错误代码。 我需要通过对errorcodes进行子串并与errorlookup表中的代码匹配来显示与id关联的所有描述。 errorlookup的示例数据: codes:description 12:Invalid 22:Inactive 21:active 代码:说

我有两个表:errorlookup和errors。 errorlookup有两列:代码和说明。 代码长度为2。 errors有两列id和errorcodes。 错误代码的长度为40,这意味着它们为每个id存储20个错误代码。 我需要通过对errorcodes进行子串并与errorlookup表中的代码匹配来显示与id关联的所有描述。 errorlookup的示例数据:

codes:description 12:Invalid 22:Inactive 21:active 代码:说明 12:无效 22:不活动 21:活动 错误的示例数据:

id:errorcodes 1:1221 2:2112 3:1222 id:错误代码 1:1221 2:2112 3:1222 我不能使用LIKE,因为它会导致太多错误。我希望errorcodes列被分解为长度为2的字符串,然后与errorlookup连接起来。
怎样才能做到呢

我认为你的
方法是正确的。MySQL有一个
RLIKE
函数,允许通过正则表达式进行匹配(我不知道它是否存在于Oracle中)。您可以使用
errorlookup.code
作为模式来匹配
错误。errorcode
(..)*
模式用于防止“1213”之类的内容匹配,例如“21”


我认为你的
方法是正确的。MySQL有一个
RLIKE
函数,允许通过正则表达式进行匹配(我不知道它是否存在于Oracle中)。您可以使用
errorlookup.code
作为模式来匹配
错误。errorcode
(..)*
模式用于防止“1213”之类的内容匹配,例如“21”


我认为最干净的解决方案是使用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;
/
您还可以基于函数创建视图,使语句更易于阅读:

create or replace view normalized_errorcodes 
as
select *
from table(unnest_errors);
然后,您可以简单地在real语句中引用视图


(我在11.2上对此进行了测试,但我认为它也应该在10.x上运行)

我认为最干净的解决方案是使用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;
/
您还可以基于函数创建视图,使语句更易于阅读:

create or replace view normalized_errorcodes 
as
select *
from table(unnest_errors);
然后,您可以简单地在real语句中引用视图


(我在11.2上对此进行了测试,但我认为它也应该在10.x上运行)

如果您真的无法更改表结构,下面是另一种方法:

创建一个辅助
编号
表格:

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 ;

如果您确实无法更改表结构,那么还有另一种方法:

创建一个辅助
编号
表格:

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 ;

重新设计表是一种选择吗?可能有一种比将20个整数存储为串联字符串更好的方法。我知道这可能是您无法控制的,但这是在单个列中组合多个数据段时遇到的问题。如果没有出现这种设计缺陷,它将被存储为单独的行,一个简单的“标准”联接将解决您的问题?可能有一种比将20个整数存储为串联字符串更好的方法。我知道这可能是您无法控制的,但这是在单个列中组合多个数据段时遇到的问题。如果没有这个设计缺陷,它将被存储为单独的行,一个简单的“标准”连接将解决您的问题。+1我发现了另一个使用交叉连接的好例子。问题被标记为“甲骨文”;如果将
交叉连接错误…
替换为
连接错误…
,oracle会发生什么情况?在MySQL中,您仍然可以得到笛卡尔积。MySQL将
交叉连接
连接
视为等价物。它允许
a连接b
(无
开启
条件)。它还允许在b.columnX=a.columnX上交叉连接b。两者都不是有效的ANSI/ISO SQL语法。Oracle将产生一个错误。+1我发现了另一个使用交叉联接的好例子。问题被标记为“甲骨文”;如果将
交叉连接错误…
替换为
连接错误…
,oracle会发生什么情况?在MySQL中,您仍然可以得到笛卡尔积。MySQL将
交叉连接
连接
视为等价物。它允许
a连接b
(无
开启
条件)。它还允许在b.columnX=a.columnX上交叉连接b。两者都不是有效的ANSI/ISO SQL语法。甲骨文将产生一个错误。