SQL - 在多行键上连接的表上使用IN

jtp*_*yda 3 sql sql-server

好的.我已经设置了一小组样本表.我只是举个例子,因为这是我能够传达问题的最佳方式.

证书表:

WorkerId    Name                             Version
----------- -------------------------------- -----------
1           Construction                     1
1           Construction                     2
1           Demolition                       1
1           Fusion                           1
5           Fusion                           1
4           Demolition                       1
4           Demolition                       2
Run Code Online (Sandbox Code Playgroud)

CertDesc表(版本,名称形式主键):

Name                             Version     Description
-------------------------------- ----------- -----------------------------------------------------------------------------------------
Construction                     1           Basic Construction -- Required for all construction workers.
Construction                     2           Full Construction -- Required for all construction managers.
Demolition                       1           Demolition -- Explosives --  Required for demolition managers.
Fusion                           1           Fusion System Control -- Includes catastrophic super-criticality recovery.
Demolition                       2           Large Scale Demolition -- Basic fission knowledge with full chemical cert.
Run Code Online (Sandbox Code Playgroud)

现在.我想获得所有CertDesc行的列表,以便WorkerId 1没有该证书.对于X = 1,我应该只获得拆迁2.

这是对我来说最好的查询:

Select Distinct d.Name, d.Version, d.Description
From CertDesc d join Certs c on d.Name = c.Name and d.Version = c.Version
Where d.Name NOT IN (Select c2.Name
    From Certs c2
    Where c2.WorkerId = 1)
Run Code Online (Sandbox Code Playgroud)

此查询返回零行.问题是,无论版本号如何,都会排除拆除行.我想要的是使用IN与元组:

Select Distinct d.Name, d.Version, d.Description
From CertDesc d join Certs c on d.Name = c.Name and d.Version = c.Version
Where (d.Name, d.Version) NOT IN (Select c2.Name, c2.Version)
    From Certs c2
    Where c2.WorkerId = 1)
Run Code Online (Sandbox Code Playgroud)

不幸的是,这在SQL Server中无效.有人知道一个很好的方法吗?

Qua*_*noi 5

SELECT  *
FROM    CertDesc cd
WHERE   NOT EXISTS
        (
        SELECT  NULL
        FROM    Certs c
        WHERE   c.WorkerId = 1
                AND c.name = cd.name
                AND c.version = cd.version
        )
Run Code Online (Sandbox Code Playgroud)

,或者,如果name并且version足够,就这样:

SELECT  name, version
FROM    CertDesc
EXCEPT
SELECT  name, version
FROM    Certs
WHERE   WorkerId = 1
Run Code Online (Sandbox Code Playgroud)

编辑:后一个查询仅适用于SQL-Server 2005.