获取不在同一列中但具有指定条件的所有可能值

时间:2019-05-24 13:19:54

标签: sql oracle-sqldeveloper

我试图在这种情况下从表中获取所有值:

  • 值的长度是3
  • value的值不超过3

表格示例(simple_table):

id | name
-------------
1  | 418
2  | 223:542
3  | 54
4  | 418
5  | 418:223:100
6  | 223
7  | 999
8  | 132
9  | null
10 | 100

所以我有三种不同的课程,长度

  • 名字的长度是3
  • 姓名长度小于3
  • 姓名长度超过3

我的代码:

第一

select distinct name 
from simple_table
where name is not null  
and LENGTH( name ) = 3;

返回值

name
-------
418
223
999
132

第二:

select distinct name 
from simple_table
where name is not null  
and LENGTH( name ) > 3;

返回值

name
-------
223:542
418:223:100

代码的“主要部分”

select distinct name 
from simple_table
where name is not null  
and LENGTH( name ) = 3
and '223:542' not like CONCAT(CONCAT('%', name ), '%');

此返回

name
-------
418
999
132
100

当我尝试使用此代码时,它将导致错误

select distinct name
from simple_table
where name is not null  
and LENGTH( name) = 3
and (select distinct name
from simple_table
where name is not null
and LENGTH( name) > 3) not like in (CONCAT(CONCAT('%', name), '%'));

错误:

ORA-00936: missing expression
00936. 00000 -  "missing expression"
*Cause:    
*Action:
Error at Line: 15 Column: 50

我想要的结果是:

name
-------
999
132

3 个答案:

答案 0 :(得分:2)

您需要做的是执行EXIST子查询,以过滤掉长字符串中列出的内容,并对该子查询进行字符串匹配和分隔符。

SELECT distinct name
FROM   simple_table t1
WHERE  name IS NOT null  
  AND LENGTH(name) = 3
 AND NOT EXISTS (
    SELECT 1
    FROM   simple_table t2
    WHERE  (    t2.name LIKE '%' || ':' || t1.name || '%'  
            OR  t2.name LIKE '%' || t1.name || ':' || '%'  
           )
)

请注意,这并非完全没有错误-例如它将匹配“ 22”到“ 222:3333”。如果要更精确,则需要将查询修改为"%:X:%" OR "%:X" OR "X:%"

这是设置:

CREATE TABLE simple_table (  
  name VARCHAR2(20) NULL
);

INSERT INTO simple_table VALUES ('222');
INSERT INTO simple_table VALUES ('123');
INSERT INTO simple_table VALUES ('334');
INSERT INTO simple_table VALUES ('001');
INSERT INTO simple_table VALUES ('002');
INSERT INTO simple_table VALUES ('334:555');
INSERT INTO simple_table VALUES ('334:001');
INSERT INTO simple_table VALUES ('777:002');

结果是(来自SQL Fiddle http://sqlfiddle.com/#!4/5f88f/16

222
123

答案 1 :(得分:2)

按照我在注释中提到的线程中的说明进行操作,我有以下解决方案:

SELECT t1.name 
FROM myTable t1
WHERE LENGTH(name) = 3
AND t1.name NOT IN (
     SELECT DISTINCT REGEXP_SUBSTR(t2.name, '[^:]+', 1, LEVEL) AS data
     FROM myTable t2
     WHERE LENGTH(t2.name) > 3
     CONNECT BY REGEXP_SUBSTR(t2.name, '[^:]+', 1, LEVEL) IS NOT NULL
);

以下是此操作的演示:SQLFiddle

答案 2 :(得分:1)

使用not exists,但我会这样说:

SELECT DISTINCT st.name
FROM simple_table st
WHERE LENGTH(st.name) = 3 AND
      NOT EXISTS (SELECT 1
                  FROM simple_table st2
                  WHERE LENGTH(st2.name) > 3 AND
                        ':' || st2.name || ':' LIKE ':%' || st.name || ':%'
                 );

通过在字符串的开头和结尾添加定界符,可以说明较长字符串的开头和结尾的名称。