1

我有一张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 并且没有在他们提供 S2 的同一项目上提供任何其他服务的承包商。

1  NULL
2  D
3  E
3  C

我在 SQL 中提取数据并在 Excel 中对其进行过滤和分组,但我想找到一种在 SQL 中执行此操作的方法。使用 SQL Server 2005。

4

2 回答 2

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 的同一项目上提供任何其他服务的承包商。

我从这份声明中知道您想要只提供 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')

它将向您显示执行 S2 服务以及除 S2 之外的任何服务的所有承包商的项目。

另外,这里有一篇博客文章的链接,它帮助我在第一次学习时了解了半连接 ( EXISTS) 和反半连接 ( )的好处。NOT EXISTS

于 2013-05-21T01:21:42.433 回答
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'
于 2013-05-21T00:51:16.880 回答