table1 K
Date id
2015-01-01 10
2015-01-02 10
2015-01-03 10
2015-01-04 10
2015-01-05 10
2015-01-06 10
table2 H
Date id Holiday
2015-01-03 10 a holiday day
我想从Date
列中排除假期,并创建一个新列,如AS new_dates
。
所以输出就像:
table3输出
new_dates id
2015-01-01 10
2015-01-02 10
2015-01-04 10
2015-01-05 10
2015-01-06 10
答案 0 :(得分:4)
现在已编辑。
根据MTO的回答,我建议EXCEPT ALL
,但甲骨文有MINUS
。
select date, id from table1
MINUS
select date, id from table2
或NOT EXISTS
:
select date, id from table1 t1
where not exists (select 1 from table2 t2
where t1.date = t2.date
and t1.id = t2.id)
已修改:已将and t1.id = t2.id
添加到NOT EXISTS
版本的子选择中。
答案 1 :(得分:2)
简单
select date, id from table1
where not exists(select 'x' from table2 where table1.date = table2.date)
答案 2 :(得分:1)
Oracle 11g R2架构设置:
CREATE TABLE T1 ( "DATE", ID ) AS
SELECT DATE '2015-01-01' + LEVEL - 1, 10
FROM DUAL
CONNECT BY LEVEL < 7;
CREATE TABLE T2 ( "DATE", ID ) AS
SELECT DATE '2015-01-03', 10 FROM DUAL;
查询1 :
SELECT * FROM T1
MINUS
SELECT * FROM T2
<强> Results 强>:
| DATE | ID |
|---------------------------|----|
| January, 01 2015 00:00:00 | 10 |
| January, 02 2015 00:00:00 | 10 |
| January, 04 2015 00:00:00 | 10 |
| January, 05 2015 00:00:00 | 10 |
| January, 06 2015 00:00:00 | 10 |
查询2 :
SELECT * FROM T1
WHERE NOT EXISTS ( SELECT 'X'
FROM T2
WHERE T1.ID = T2.ID
AND T1."DATE" = T2."DATE" )
<强> Results 强>:
| DATE | ID |
|---------------------------|----|
| January, 01 2015 00:00:00 | 10 |
| January, 05 2015 00:00:00 | 10 |
| January, 04 2015 00:00:00 | 10 |
| January, 06 2015 00:00:00 | 10 |
| January, 02 2015 00:00:00 | 10 |
查询3 :
此查询在SQL Server中有效,但在Oracle中无效:
SELECT * FROM T1
EXCEPT ALL
SELECT * FROM T2
<强> Results 强>:
ORA-00933: SQL command not properly ended
答案 3 :(得分:0)
另一种方式,
SQL> SELECT t1.* FROM t1, t2 WHERE t1."DATE" <> t2."DATE" AND t1.ID = t2.ID;
DATE ID
--------- ----------
01-JAN-15 10
02-JAN-15 10
04-JAN-15 10
05-JAN-15 10
06-JAN-15 10
不同的ID可能有不同的假期,因此条件会检查不匹配的行并将其过滤掉并确保检查特定的ID而不是随机的。
从性能的角度来看,通过适当的主键和外键约束,您可以在引用表上执行单个表扫描,而不是2个表扫描。
例如,
添加主键和外键约束:
SQL> ALTER TABLE t1
2 ADD CONSTRAINT t1_pk PRIMARY KEY ("DATE", id);
Table altered.
SQL>
SQL> ALTER TABLE t2
2 ADD CONSTRAINT t2_fk
3 FOREIGN KEY ("DATE", ID)
4 REFERENCES t1 ("DATE", id);
Table altered.
让我们检查解释计划:
SQL> set autot on explain
SQL> SELECT t1.* FROM t1, t2 WHERE t1."DATE" <> t2."DATE" AND t1.ID = t2.ID;
DATE ID
--------- ----------
01-JAN-15 10
02-JAN-15 10
04-JAN-15 10
05-JAN-15 10
06-JAN-15 10
Execution Plan
----------------------------------------------------------
Plan hash value: 603358195
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5 | 110 | 4 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 5 | 110 | 4 (0)| 00:00:01 |
| 2 | TABLE ACCESS FULL| T2 | 1 | 11 | 3 (0)| 00:00:01 |
|* 3 | INDEX FULL SCAN | T1_PK | 5 | 55 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("T1"."ID"="T2"."ID")
filter("T1"."DATE"<>"T2"."DATE" AND "T1"."ID"="T2"."ID")
Note
-----
- this is an adaptive plan
因此,只有T2
上的全表扫描和T1
的主键索引上的 INDEX FULL SCAN 。< / p>
现在,外键应该有一个支持索引,这将避免全表扫描并使用索引扫描。
让我们为外键创建支持指数:
SQL> CREATE INDEX t2_indx ON t2("DATE", id);
Index created.
让我们检查解释计划:
SQL> set autot on explain
SQL> SELECT t1.* FROM t1, t2 WHERE t1."DATE" <> t2."DATE" AND t1.ID = t2.ID;
DATE ID
--------- ----------
01-JAN-15 10
02-JAN-15 10
04-JAN-15 10
05-JAN-15 10
06-JAN-15 10
Execution Plan
----------------------------------------------------------
Plan hash value: 2278991468
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5 | 110 | 2 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 5 | 110 | 2 (0)| 00:00:01 |
| 2 | INDEX FULL SCAN| T2_INDX | 1 | 11 | 1 (0)| 00:00:01 |
|* 3 | INDEX FULL SCAN| T1_PK | 5 | 55 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("T1"."ID"="T2"."ID")
filter("T1"."DATE"<>"T2"."DATE" AND "T1"."ID"="T2"."ID")
Note
-----
- this is an adaptive plan
现在,没有全表扫描,而优化程序使用 INDEX FULL SCAN 。