SQL:排除查找

时间:2016-01-19 10:06:19

标签: sql many-to-many self-join

我有这样的数据结构:

table

我必须找到所有没有PHONE_TYPE = 2

的人

我用这样的查询解决了这个问题:

SELECT DISTINCT NAME FROM table WHERE NAME NOT IN (
SELECT S2.NAME FROM table S2
LEFT OUTER JOIN table S1
ON S1.PHONE_TYPE != 2 AND S2.PHONE_TYPE = S1.PHONE_TYPE
WHERE S1.PHONE_TYPE is null);
  • 有更复杂的方法吗?
  • 当您有many-to-many关系时,搜索的标准解决方案是什么?

4 个答案:

答案 0 :(得分:3)

这是NOT EXISTS的任务:

select distinct name
from table as t1
where not exists
 ( select *
   from table as t2
   where t1.name = t2.name
     and t2.phone_type = 2
 )

答案 1 :(得分:3)

试试这个

select name from table
group by name having max(case when phone_type=2 then 1 else 0 end)=0

答案 2 :(得分:2)

理想情况下,你会有三张桌子;值得一看的是参照完整性。见https://docs.oracle.com/cd/B19306_01/server.102/b14220/data_int.htm

您将拥有以下表格: -

enter image description here

我分成三个表的原因是因为我认为您的上述数据结构需要规范化。见https://en.wikipedia.org/wiki/Database_normalization

  
      
  1. 从不受欢迎的插入,更新和删除依赖项中释放关系集合;
  2.   
  3. 随着新类型数据的引入,减少重建关系集合的需要,从而延长应用程序的使用寿命;
  4.   
  5. 使关系模型对用户更具信息性;
  6.   
  7. 使查询统计信息的关系集合中立,这些统计信息随着时间的推移可能会发生变化。    - E.F. Codd,“数据库关系模型的进一步规范化”[8]
  8.   

我强烈建议为您的人员和电话类型表使用主键。我更喜欢代理键,例如UUID,但请参阅http://sqlmag.com/business-intelligence/surrogate-key-vs-natural-key以确定最适合您的设置。

您可以使用以下查询然后拉出行: -

SELECT p.NAME FROM PERSON as p
WHERE p.id NOT IN (SELECT person_id FROM PersonPhone WHERE phone_id = 2)

您通常希望摆脱许多关系,因为您最终在数据库中存在冗余数据,最终可能会导致一些问题。

答案 3 :(得分:1)

您还可以使用NOT IN条件:

SELECT * from table
where name not in(select name from table where phone_type = 2)