ORACLE SQL语句查询一个字段在另一表字段中有两条或以上 的数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ORACLE SQL语句查询一个字段在另一表字段中有两条或以上 的数据相关的知识,希望对你有一定的参考价值。

参考技术A

1、创建两张测试表,

create table test_student(student_id varchar2(20), student_name varchar2(20));

create table test_class(student_id varchar2(20), class_id varchar2(20));

2、插入测试数据

insert into test_student values(1001,'陈XX');

insert into test_student values(1002,'许XX');

insert into test_student values(1003,'张XX');

insert into test_student values(1004,'吴XX');

insert into test_class values (1001,'C01');

insert into test_class values (1001,'C02');

insert into test_class values (1002,'C01');

insert into test_class values (1003,'C01');

insert into test_class values (1004,'C01');

insert into test_class values (1004,'C02');

3、查询表的记录,select t.*, rowid from test_class t;

4、编写sql,查询出来test_student表中在test_class表中是多条而不是单条的记录,可以看到1001、1004学生是有多条记录的,

select t.student_id, 

       count(1) a

  from test_student t , test_class b

 where t.student_id = b.student_id

 group by t.student_id

 having count(*)>1,

在另一个字段Oracle SQL中包含的一个字段中查找文本

如果有人提出这个问题,我很抱歉,我无法用语言表达。

我被要求过滤出查询中的行,其中来自一个字段的文本包含在另一个字段中。一个例子可能会更好地解释它:

    Column_1         Column_2
    Low Static       Static
    Static           Static
    Static           Clear
                     Static
    Very Low Freq    Freq

查询的结果应仅返回第3行和第4行,因为第1,2和5行包含相似的字符串。现在,我有以下条件:

    WHERE
    ((Column_2 NOT LIKE '%' || Column_1 || '%')
    OR (Column_1 NOT LIKE '%' || Column_2 || '%' OR Column_1 IS NULL))

但是,当我只想返回第3行和第4行时,它返回第1,3,4和5行。这只是示例数据,我的实际数据集在第1列和第2列包含许多不同的文本字符串,所以我不能只是编写特定的case语句来驱逐列相似的某些实例。

也许这是不可能的,因为我无法将字符串定义为2个空格中包含的内容,同时考虑到没有空格的情况?

谢谢

答案

为了你的表达,我认为你想要and而不是or

WHERE ((Column_2 NOT LIKE '%' || Column_1 || '%') AND
       (Column_1 NOT LIKE '%' || Column_2 || '%' OR Column_1 IS NULL)
      )

你需要两个条件都是真的。您可能会发现逻辑更容易理解为:

WHERE NOT (Column_2 LIKE '%' || Column_1 || '%' OR
           Column_1 LIKE '%' || Column_2 || '%'
          )
另一答案

您要使用的方法是进行全表扫描,因此随着表的增长它不会扩展。如果要实现将使用索引的更有效的解决方案(不使用Oracle大文本索引),请使用基于函数的索引预先计算列公共子串。

使用INSTR(),您可以查找列是否是另一列的子字符串,并返回该分数。 0表示不匹配。

create index ix_t_score on t (instr(nvl(column_1,' '), nvl(column_2, ' ')),
                              instr(nvl(column_2,' '), nvl(column_1, ' ')));

现在编写查询,以便Oracle允许Oracle使用索引。

-- Find rows that don't have common strings
select * from t
  where instr(nvl(column_1, ' '), nvl(column_2, ' ')) = 0 and
        instr(nvl(column_2, ' '), nvl(column_1, ' ')) = 0;

-- Find rows that do
select * from t
  where instr(nvl(column_1, ' '), nvl(column_2, ' ')) > 0 or
        instr(nvl(column_2, ' '), nvl(column_1, ' ')) > 0;


set autotrace on


Execution Plan
----------------------------------------------------------
Plan hash value: 4100696360

---------------------------------------------------------------------------------
| Id  | Operation         | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |             |     1 |    22 |     2   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE   |             |     1 |    22 |            |          |
|*  2 |   INDEX RANGE SCAN| IX_T_SCORE  |     1 |    22 |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access(INSTR(NVL("COLUMN_1",' '),NVL("COLUMN_2",' '))=0 AND
              INSTR(NVL("COLUMN_2",' '),NVL("COLUMN_1",' '))=0)

您可以通过创建确定性存储过程/函数来返回分数来简化它,并且SQL变得比上面简单得多。使用NVL()是为了处理带空值的列。

以上是关于ORACLE SQL语句查询一个字段在另一表字段中有两条或以上 的数据的主要内容,如果未能解决你的问题,请参考以下文章

求oracle中查询关联查询不同数据在另一表作为相同字段的对应的值

在sql语句中怎么判断一个字段是不是包含在另一个字符串中

SQL语句循环一张表的一个字段ID,根据这个字段的内容去修改另一张表,

sql语句中如何一个字段对查询出的多个值添加判断条件

如何解决ORACLE中表一得列名的别名为另一表中的某一字段的值?

在另一个字段Oracle SQL中包含的一个字段中查找文本