【问题标题】:Getting all posible values which are not in the same column but with specified conditions获取不在同一列中但具有指定条件的所有可能值
【发布时间】:2019-10-11 02:37:06
【问题描述】:

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

  • 长度为3
  • 值不在大于 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

【问题讨论】:

  • 如果这是用 t-sql 编写的 - 您必须在最后一行中去掉“IN”运算符 - 不确定这是否适用于 Oracle
  • 首先,这不是存储这些数字的好方法,而且这种设计导致了 99% 的问题。其次,你得到的错误来自LENGTH( name) > 3) not like in (CONCAT(CONCAT('%', name), '%')); 这是不正确的语法,但修复它没有什么意义,因为它根本不会做你想要的。为了拆分该字符串,请查看此线程:stackoverflow.com/questions/26878291/…

标签: sql oracle-sqldeveloper


【解决方案1】:

您需要做的是执行 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

【讨论】:

    【解决方案2】:

    按照我在cmets中提到的线程中的说明,我有以下解决方案:

    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

    【讨论】:

      【解决方案3】:

      使用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 || ':%'
                       );
      

      通过在字符串的开头和结尾添加分隔符,您可以考虑较长字符串开头和结尾的名称。

      【讨论】:

        猜你喜欢
        • 2023-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-14
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        相关资源
        最近更新 更多