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));
这是我的查询
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));