如何编写一个Sql查询来查找从未满足以下“不在哪里(a = x和b = x)”的不同值

时间:2013-01-02 15:40:48

标签: sql sql-server-2008

我有下表Attributes

* AttId  * CustomerId  * Class * Code *
| 1      | 1           | 1     | AA   |
| 2      | 1           | 1     | AB   |
| 3      | 1           | 1     | AC   |
| 4      | 1           | 2     | AA   |
| 5      | 1           | 2     | AB   |
| 6      | 1           | 3     | AB   |
| 7      | 2           | 1     | AA   |
| 8      | 2           | 1     | AC   |
| 9      | 2           | 2     | AA   |
| 10     | 3           | 1     | AB   |
| 11     | 3           | 3     | AB   |
| 12     | 4           | 1     | AA   |
| 13     | 4           | 2     | AA   |
| 14     | 4           | 2     | AB   |
| 15     | 4           | 3     | AB   |

每个ClassCode配对代表特定的Attribute

我正在尝试编写一个查询,该查询返回与customers配对Attribute关联的的所有Class = 1, Code = AB

这将返回Customer Id值2和4。

我开始编写Select Distinct A.CustomerId From Attributes A Where (A.Class = 1 and A.Code = 'AB')但当我意识到我正在编写SQL查询并且在括号之前没有可用的运算符来指示其中的子句必须不<时停止/ strong>得到满足。

我错过了什么?或者我应该看哪个操作员?

修改

我正在尝试编写一个查询,该查询仅返回Customers配对Attribute NO 链接的Class = 1, Code = AB(即不同的客户ID)

这只能是Customer Id值2和4,因为表包含行:

* AttId  * CustomerId  * Class * Code *
| x      | 2           | 1     | AB   |
| x      | 4           | 1     | AB   |

更改标题:

如何在Sql查询中写“不在哪里(a = x和b = x)”

要:

如何编写Sql查询以查找从未满足以下条件的不同值“Where not(a = x和b = x)”

由于前一个标题本身就是一个问题,但问题的细节增加了额外的维度,导致混淆。

5 个答案:

答案 0 :(得分:4)

一种方法是

SELECT DISTINCT CustomerId FROM Attributes a 
WHERE NOT EXISTS (
    SELECT * FROM Attributes forbidden 
    WHERE forbidden.CustomerId = a.CustomerId AND forbidden.Class = _forbiddenClassValue_ AND forbidden.Code = _forbiddenCodeValue_
)

或加入

SELECT DISTINCT a.CustomerId FROM Attributes a
LEFT JOIN (
    SELECT CustomerId FROM Attributes
    WHERE Class = _forbiddenClassValue_ AND Code = _forbiddenCodeValue_
) havingForbiddenPair ON a.CustomerId = havingForbiddenPair.CustomerId
WHERE havingForbiddenPair.CustomerId IS NULL

另一种方法是使用EXCEPT,根据ypercube的回答

答案 1 :(得分:3)

由于没有人发布简单的逻辑语句,因此它是:

select . . .
where A.Class <> 1 OR A.Code <> 'AB'

(X和Y)的负数是(不是X或不是Y)。

我知道,这是一个分组的事情。为此,您使用聚合并具有:

select customerId
from Attributes a
group by CustomerId
having sum(case when A.Class = 1 and A.Code = 'AB' then 1 else 0 end) = 0

我总是喜欢使用这种技术解决“是否在一组”类型的问题。

答案 2 :(得分:3)

SELECT CustomerId 
FROM Attributes

EXCEPT

SELECT CustomerId 
FROM Attributes
WHERE Class = 1
  AND Code = AB ;

答案 3 :(得分:1)

Select Distinct A.CustomerId From Attributes A Where not (A.Class = 1 and A.Code = 'AB')

答案 4 :(得分:0)

试试这个:

SELECT DISTINCT A.CustomerId From Attributes A Where 
0 = CASE 
         WHEN A.Class = 1 and A.Code = 'AB' THEN 1 
         ELSE 0 
END

编辑:当然这还为你提供了1(doh!),你应该理想地使用pjotrs NOT EXISTS查询,为我提供足够紧密的数据服务:)