想象一下,如果我有两张这样的表:
Table Name: user
| id | user_id | password |
Table Name: permissions
| id | admin | write | delete | transfer |
用这个填充表格:
Inserting into user table:
- 0, joshsh, asdf01
- 1, jakesh, asdf02
- 2, annsh, asdf03
- 3, lamsh, asdf04
Inserting into permissions table:
- 0, yes, yes, yes, yes
- 1, yes, yes, yes, yes
- 2, no, yes, yes, yes
我没有将第4个值添加到permissions
表中。我如何查询语句以找到我忘记的数字(如果它是一个大数据库)?
答案 0 :(得分:2)
假设id列是基于id列的权限和用户表之间的连接(并且该id是两个表中的主要/唯一键),这里有几个解决方案:
select id from permissions
minus
select id from user;
或
select * from user
where id not in (select id from permissions);
答案 1 :(得分:2)
有很多方法可以获得相同的结果,这有两种可能的方式:
使用NOT EXISTS:
SQL> select u.*
2 from user_ u
3 where not exists (
4 select 1
5 from permissions p
6 where u.id = p.id
7 );
ID USER_ID PASSWORD
---------- ---------- ----------
3 lamsh asdf04
Execution Plan
----------------------------------------------------------
Plan hash value: 3342498783
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 160 | 7 (15)| 00:00:01 |
|* 1 | HASH JOIN ANTI | | 4 | 160 | 7 (15)| 00:00:01 |
| 2 | TABLE ACCESS FULL| USER_ | 4 | 108 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| PERMISSIONS | 3 | 39 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("U"."ID"="P"."ID")
Note
-----
- dynamic sampling used for this statement (level=2)
使用外部联接:
SQL> select u.*
2 from user_ u
3 left outer join permissions p
4 on (u.id = p.id)
5 where p.id is null;
ID USER_ID PASSWORD
---------- ---------- ----------
3 lamsh asdf04
Execution Plan
----------------------------------------------------------
Plan hash value: 3342498783
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 160 | 7 (15)| 00:00:01 |
|* 1 | HASH JOIN ANTI | | 4 | 160 | 7 (15)| 00:00:01 |
| 2 | TABLE ACCESS FULL| USER_ | 4 | 108 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| PERMISSIONS | 3 | 39 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("U"."ID"="P"."ID")
Note
-----
- dynamic sampling used for this statement (level=2)
请注意,Oracle对两个语句执行了相同的解释计划,考虑到测试是使用两个非常小的表而没有索引而没有统计信息。 另外,考虑到有很多方法可以获得相同的结果;性能很大程度上取决于您的数据,统计数据,索引......
ps我使用USER_
代替USER
,以避免出现问题。
答案 2 :(得分:0)
如果两个表不相等,则对两个表应用count(*),然后生成alert,并且可以使用sql server agent job生成alter。 或者你可以做到这一点 从用户中选择*作为u 完全外部联接权限为p 在a.id中(从用户中选择id)
答案 3 :(得分:0)
最好的方法是在where子句中使用LEFT JOIN和IS NULL,它在每个方面都优雅高效:
SELECT u.*
FROM user u
LEFT JOIN permissions p ON u.id = p.id
WHERE p.id IS NULL