Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 左连接并排除某些匹配上不存在的行_Sql_Oracle_Join - Fatal编程技术网

Sql 左连接并排除某些匹配上不存在的行

Sql 左连接并排除某些匹配上不存在的行,sql,oracle,join,Sql,Oracle,Join,我想查询表2中缺少的关于PROP1、PROP2元组(如a、b、3)的NUM值。但是,如果表2中不存在元组,例如a、b。我不想在结果中返回它 因此,我的预期输出是 PROP1 PROP2 NUM a a 3 在我编写的查询之后,还返回a、b元组,我不想这样做 SELECT * FROM TABLE1 T1 LEFT JOIN TABLE2 T2 ON T1.PROP1 = T2.PROP1 AND T1.PROP2 = T2.PROP2 AND T1.NUM =

我想查询表2中缺少的关于PROP1、PROP2元组(如a、b、3)的NUM值。但是,如果表2中不存在元组,例如a、b。我不想在结果中返回它

因此,我的预期输出是

PROP1   PROP2   NUM
a       a       3
在我编写的查询之后,还返回a、b元组,我不想这样做

SELECT *
FROM TABLE1 T1
LEFT JOIN TABLE2 T2 ON T1.PROP1 = T2.PROP1 AND T1.PROP2 = T2.PROP2 AND T1.NUM = T2.NUM
WHERE T2.NUM IS NULL
我想排除这3行,所以我再次加入表2并对结果进行分组,从而得到正确的结果

SELECT T1.PROP1, T1.PROP2, T1.NUM
FROM TABLE1 T1
LEFT JOIN TABLE2 T2 ON T1.PROP1 = T2.PROP1 AND T1.PROP2 = T2.PROP2 AND T1.NUM = T2.NUM
JOIN TABLE2 T22 ON T1.PROP1 = T22.PROP1 AND T1.PROP2 = T22.PROP2
WHERE T2.NUM IS NULL
GROUP BY T1.PROP1, T1.PROP2, T1.NUM
问:有没有什么方法可以不用GROUPBY语句来完成,因为它对于大型表来说有点详尽


我正在使用Oracle 11g。

这将满足您的要求,但我不知道它是否更高效:

SELECT *
FROM TABLE1 T1 JOIN
     (SELECT DISTINCT PROP1, PROP2
      FROM TABLE2
     ) TT2
     ON T1.PROP1 = TT2.PROP1 AND t1.PROP2 = TT2.PROP2 LEFT JOIN
     TABLE2 T2
     ON T1.PROP1 = T2.PROP1 AND T1.PROP2 = T2.PROP2 AND T1.NUM = T2.NUM
WHERE T2.NUM IS NULL;

它首先过滤匹配行上的table1,然后进行最终比较。

这就是我应该做的

with table1 as
(select 'a' prop1, 'a' prop2, 1 num from dual
union all
select 'a' , 'a' , 2  from dual
union all
select 'a' , 'a' , 3  from dual
union all
select 'a' , 'b' , 1  from dual
union all
select 'a' , 'b' , 2  from dual
union all
select 'a' , 'b' , 3 from dual),
table2 as(
select 'a' prop1, 'a' prop2, 1 num from dual
union all
select 'a' , 'a' , 2  from dual
)
select prop1, prop2, num
from table1
where (prop1, prop2) in (select prop1, prop2 from table2)
minus
select prop1, prop2, num
from table2
另一种方法是:

select prop1, prop2, num
from table1
where (prop1, prop2, num) not in(select prop1, prop2, num
from table2)
and (prop1, prop2) in (select prop1, prop2 from table2)
编辑: 我试着用exists来获得它,只使用了一次表2,但我没有找到解决方案,如果其他人找到解决方案,我会感兴趣。

根据Gordon关于性能的回答,IS NULL可能是性能问题

为NULL将禁止使用索引。因为空值没有索引

有两种方法可以使用带为NULL的索引:

1.位图索引。但是,更适用于OLTP系统

2.我最喜欢的方式,很好演示。我们可以使b-树索引的叶子保持不变。因此,在查询NULL时使用索引。基本上,空值都在一起,位于索引的顶部/底部。Oracle可以向前或向后使用索引,所以这并不重要。它会对索引进行完整扫描

我在这里回答了一个类似的问题

由于OR为null条件,第一个场景将不使用索引:

让我们使树叶保持不变:

我在这里回答了一个类似的问题,

谢谢,T中有一个输入错误!顺便说一句,在我看来,整个左连接方法是个坏主意。如果左连接不存在,为什么要使用左连接来提问?
select prop1, prop2, num
from table1
where (prop1, prop2, num) not in(select prop1, prop2, num
from table2)
and (prop1, prop2) in (select prop1, prop2 from table2)
SQL> SELECT * FROM PROD_NEW; PROFILE_TYPE --------------- Prod Prodparallel Prod SQL> CREATE INDEX PROD_NEW_I1 ON PROD_NEW 2 (PROFILE_TYPE 3 ); Index created. SQL> EXPLAIN PLAN FOR SELECT * FROM PROD_NEW WHERE PROFILE_TYPE = 'Prod' OR PROFILE_TYPE IS NULL; Explained. SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- Plan hash value: 2121244107 ------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 3 | 15 | 3 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| PROD_NEW | 3 | 15 | 3 (0)| 00:00:01 | ------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- 1 - filter("PROFILE_TYPE" IS NULL OR "PROFILE_TYPE"='Prod') 13 rows selected SQL> DROP INDEX PROD_NEW_I1; Index dropped. SQL> CREATE INDEX PROD_NEW_I1 ON PROD_NEW 2 (PROFILE_TYPE,1 3 ); Index created. SQL> EXPLAIN PLAN FOR SELECT * FROM PROD_NEW WHERE PROFILE_TYPE = 'Prod' OR PROFILE_TYPE IS NULL; Explained. SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- Plan hash value: 1272076902 -------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 3 | 15 | 1 (0)| 00:00:01 | |* 1 | INDEX FULL SCAN | PROD_NEW_I1 | 3 | 15 | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------- 1 - filter("PROFILE_TYPE" IS NULL OR "PROFILE_TYPE"='Prod') 13 rows selected. SQL>