返回具有给定属性的表中出现的各种实例的行

时间:2014-01-18 17:23:43

标签: sql

例如,给出了架构:

account(id, type, cname)

我想使用cname中显示的每个type帐户返回account个客户。

以下查询将执行:

SELECT cname, type
FROM account AS cust_account 
WHERE NOT EXISTS ( 
    SELECT type 
    FROM account 
    EXCEPT
    SELECT type 
    FROM account 
    WHERE account.cname = cust_account.cname
);

但是,我无法理解它背后的逻辑。特别是,我没有看到EXCEPT语句发生了什么。任何人都可以澄清一下吗?谢谢。

2 个答案:

答案 0 :(得分:5)

WHERE NOT EXIST子句处理每条记录时,它会为该记录中的客户运行以下步骤。如果它看到第3步中的空列表,则会将客户包含在查询结果中(NOT EXISTS)。

  1. 列出所有可能的帐户类型。
  2. 列出该客户拥有的所有帐户类型。
  3. 从步骤#1中的列表中减去步骤#2 中的列表。这将创建该客户没有的任何帐户类型的列表。对于拥有所有帐户的客户,这将是空的。
  4. 要明确的是,由于WHERE NOT EXIST子句包含相关子查询,因此对于帐户表中的EACH行,将执行步骤1-3(由子查询执行)一次。例如,如果accounts表包含100,000,则子查询将运行100,000次。

答案 1 :(得分:1)

基本上,原始查询只会显示那些没有(WHERE NOT EXISTS)类型[帐户](SELECT type FROM account WHERE account.cname = cust_account.cname)类型的客户(EXCEPT)类型列表(SELECT type FROM account)< =>没有(WHERE NOT EXISTS)所有类型的帐户。

编写此查询的一种更简单的方法是:

SELECT  x.cname
FROM    dbo.Account x
GROUP BY x.cname
HAVING  COUNT(DISTINCT x.type) = (SELECT COUNT(DISTINCT y.type) FROM dbo.Account y)

或者

SELECT  a.cname, a.type
FROM    dbo.Account a
WHERE   a.cname IN
(
    SELECT  x.cname
    FROM    dbo.Account x
    GROUP BY x.cname
    HAVING  COUNT(DISTINCT x.type) = (SELECT COUNT(DISTINCT y.type) FROM dbo.Account y)
)