Oracle DB:就像有多个值

Oracle DB : Like with multiple values

这是我的查询

SELECT dia
FROM CRES
WHERE pro_id = 2
AND 8103434563 LIKE
  ( SELECT dial_pattern||'%' FROM CDIVN WHERE dial_id = 1
  );

现在 select dial_pattern||'%' from CDIVN where dial_id = 1 可以给出 multiple 结果。因此,我的主要查询失败了,原因是 "sub query returns more than one row"。这是因为我提到了like

但我的逻辑需要 like 因为我想要 8103434563 具有来自 table CDIVN 的模式匹配条件。

如何修改我的查询。请帮忙。

=======

 CREATE TABLE CDIVN
   (    DIAL_PATTERN_ID NUMBER NOT NULL ENABLE, 
    DIAL_PATTERN VARCHAR2(30 BYTE) NOT NULL ENABLE, 
    OTHERS VARCHAR2(64 BYTE), 
     CONSTRAINT "CDIVN_PK" PRIMARY KEY ("DIAL_PATTERN_ID", "DIAL_PATTERN")

   );


Insert into CDIVN (DIAL_PATTERN_ID,DIAL_PATTERN,OTHERS) values (1,'810','abc');
Insert into CDIVN (DIAL_PATTERN_ID,DIAL_PATTERN,OTHERS) values (1,'811','xyz');
Insert into CDIVN (DIAL_PATTERN_ID,DIAL_PATTERN,OTHERS) values (1,'812','aaa');
Insert into CDIVN (DIAL_PATTERN_ID,DIAL_PATTERN,OTHERS) values (5,'999','www');
Insert into CDIVN (DIAL_PATTERN_ID,DIAL_PATTERN,OTHERS) values (9,'333','ewe');


  CREATE TABLE CRES
   (    PROFILE_ID NUMBER NOT NULL ENABLE, 
    PROFILE_NAME VARCHAR2(50 BYTE) NOT NULL ENABLE, 
    DIALLED_PATTERN VARCHAR2(15 BYTE), 
     CONSTRAINT "CRES_PK" PRIMARY KEY ("PROFILE_ID")

   ) ;


Insert into CRES (PROFILE_ID,PROFILE_NAME,DIALLED_PATTERN) values (1,'A','1');
Insert into CRES (PROFILE_ID,PROFILE_NAME,DIALLED_PATTERN) values (2,'B','5');
Insert into CRES (PROFILE_ID,PROFILE_NAME,DIALLED_PATTERN) values (3,'C','9');

我有 CRES-profile id 和一个来自其他来源的号码,分别是 1 和 81034345。

现在select DIALLED_PATTERN from CRES where PROFILE_ID=1;

这将给我 DIALLED_PATTERN 作为 1。

现在select DIAL_PATTERN from CDIVN where DIALLED_PATTERN_ID = 1 ( DIALLED_PATTERN )

这将 DIAL_PATTERN 作为 810、811、812。

现在如果 81034345 与 810% 或 811% 或 812% 中的任何一个匹配。那么我需要 810% 作为我的答案。

如果我可以这么说,我也疯狂地痴迷于 sql 拥有 IN LIKE 功能。为此,您可以将其写为 JOIN on table CRES.

而不是将子查询放入条件中

我的看法是子查询

( SELECT dial_pattern||'%' FROM CDIVN WHERE dial_id = 1
  );
标准中的

不直接影响 table CRES 中的行,而是用作所有结果的过滤器。意思是,如果子查询没有 return (a) 值,整个查询也不应该 return 任何东西。

你的方向是正确的,只是你需要JOIN两个表,不需要子查询,你可以直接使用LIKE dial_pattern||'%'

SQL> SELECT a.*, b.*
  2  FROM CRES A
  3  JOIN CDIVN b
  4  ON (b.DIAL_PATTERN_ID = A.profile_id)
  5  WHERE TO_CHAR(8103434563) LIKE dial_pattern||'%';

PROFILE_ID PROFILE_NAME DIALLED_PATTERN DIAL_PATTERN_ID DIAL_PATTER OTHERS
---------- ------------ --------------- --------------- ----------- ------
         1 A            1                             1 810         abc

如果我理解正确的话,我会选择:

SELECT dia
FROM   CRES
WHERE  pro_id = 2
AND    exists (
         SELECT null
         FROM   CDIVN
         WHERE  dial_id = 1 and
                TO_CHAR(8103434563) like dial_pattern||'%');

收集相似值并构建正则表达式,例如

-- Test Data
with CDIVN as
 (select 1 as dial_id, 'ABC' as val
    from dual
  union all
  select 1 as dial_id, 'ACD' as val
    from dual
  union all
  select 1 as dial_id, 'XXA' as val from dual),

CRES as
 (select 2 as proc_id, 'ABCD' as val
    from dual
  union all
  select 2 as proc_id, 'DABCD' as val
    from dual
  union all
  select 2 as proc_id, 'ACF' as val
    from dual
  union all
  select 2 as proc_id, 'XXAF' as val from dual)

,
-- Build regexp expression: 1, 'ABC|ACD|XXA'
CDIVN_PATTERN as
 (select dial_id,
         listagg(val, '|') within group(order by dial_id) as val_pattern
    from CDIVN
   group by dial_id)

-- Use this expression by regexp_like
select *
  from CRES c
 where regexp_like(c.val,
                   (select '^' || p.val_pattern
                      from cdivn_pattern p
                     where p.dial_id = 1));