我有一张project
表。每行都是项目的服务或产品。
Project Contractor Service
======= ========== =======
1 B S1
1 A S2
1 A S3
1 C S1
2 D S2
2 A S1
2 B S3
3 E S2
3 B S1
3 C S2
我想找到在项目中提供S2的承包商,并且没有在他们提供的同一项目上提供任何其他服务。
1 NULL
2 D
3 E
3 C
我在SQL中提取数据并进行过滤并将其分组到Excel中,但我想在SQL中找到一种方法。使用SQL Server 2005。
答案 0 :(得分:2)
我会选择反半连接(NOT EXISTS
语句):
SELECT AllS2.[Project],
AllS2.[Contractor],
AllS2.[Service]
FROM [StackoverflowProjects] AllS2
WHERE AllS2.[Service] = 'S2'
AND NOT EXISTS (SELECT NULL
FROM StackoverflowProjects NonS2
WHERE AllS2.Project = NonS2.Project
AND AllS2.Contractor = NonS2.Contractor
AND AllS2.Service <> 'S2')
如果您需要帮助解释,请告诉我。但它确实有效。
首先让我指出,我将这些别名重命名为不那么抽象,希望更有帮助。
我想找到在项目上提供S2的承包商,并且没有在他们提供的同一个项目上提供任何其他服务。
我从这个声明中知道你想要的承包商只提供S2服务。如果您还不熟悉NOT
部分,那么EXISTS
部分可能会有点棘手。
因此,让我做相反的事情并解释它的作用:
SELECT AllS2.[Project],
AllS2.[Contractor],
AllS2.[Service]
FROM [StackoverflowProjects] AllS2
WHERE AllS2.[Service] = 'S2'
AND EXISTS (SELECT NULL
FROM StackoverflowProjects NonS2
WHERE AllS2.Project = NonS2.Project
AND AllS2.Contractor = NonS2.Contractor
AND AllS2.Service <> 'S2')
将向您展示所有承包商&#39;执行S2服务的项目以及S2以外的任何服务。
此外,这里有link to a blog article帮助我了解半连接(EXISTS
)和反半连接(NOT EXISTS
)在我第一次学习时的好处。< / p>
答案 1 :(得分:0)
;WITH ServiceCount AS (
-- Contractor projects that have only one service
SELECT Project, Contractor, COUNT(*) as [Count]
FROM Projects
GROUP BY Project, Contractor
HAVING COUNT(*) = 1
)
SELECT
sc.Project,
sc.Contractor
FROM ServiceCount sc
JOIN Projects p
ON p.Project = sc.Project
AND p.Contractor = sc.Contractor
WHERE p.Service = 'S2'