SQL:不包括查找

SQL: excluding look up

我有这样的数据结构:

我必须找到所有没有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);

理想情况下,您将拥有三个表;可能值得看一下什么是 referential integrity。参见 https://docs.oracle.com/cd/B19306_01/server.102/b14220/data_int.htm

您将拥有以下表格:-

之所以分成三张表是因为我相信你上面的数据结构需要规范化。参见 https://en.wikipedia.org/wiki/Database_normalization

  1. To free the collection of relations from undesirable insertion, update and deletion dependencies;
  2. To reduce the need for restructuring the collection of relations, as new types of data are introduced, and thus increase the life span of application programs;
  3. To make the relational model more informative to users;
  4. To make the collection of relations neutral to the query statistics, where these statistics are liable to change as time goes by. — E.F. Codd, "Further Normalization of the Data Base Relational Model"[8]

我强烈建议为您的个人和 phone 类型表准备主键。我更喜欢代理键,例如 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)

您通常希望摆脱 many-many 关系,因为您最终会在数据库中拥有冗余数据,这最终可能会给您带来一些问题。

您也可以像这样使用 NOT IN 条件:

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

这是 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
 )

也试试这个

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