开发者

SQL -- Using IN over tables joined on multiple-row key

Alright. I've got a small set of sample tables set up. I'll just give the example because it's the best way I can communicate the issue.

Certs Table:

WorkerId    Name                             Version
----------- -------------------------------- -----------
1           Construction                     1
1           Construction                     2
1           Demolition                       1
1           Fusion                           1
5           Fusion                           1
4           Demolition                       1
4           Demolition                       2

CertDesc Table (Version, Name form Primary Key):

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.

Now. I want to get a list of all CertDesc rows such that WorkerId 1 does NOT have that cert. For X = 1, I should only get Demolition 2.

Here's the almost-there query that looks the best to me:

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)

This query returns zero rows. The problem is that Demolition rows get excluded regardless of the version number. What I would like is to use IN with tuples:

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)

Unfortunately, this is invalid in SQL Server. Does anybody know a good way to get at this?


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
        )

, or, if name and version are enough, just this:

SELECT  name, version
FROM    CertDesc
EXCEPT
SELECT  name, version
FROM    Certs
WHERE   WorkerId = 1

Edit: This latter query only works with SQL-Server 2005.


Would something like this work:

 select c.WorkerId, c.Name as workername, cd.version, 
       cd.name as certificatename
  from certs as c
 cross join certdesc as cd 
 where cd.version <> c.version
   and cd.name <> c.name
 order by c.workerid

To compare:

select c.WorkerId, c.Name as workername, cd.version, 
       cd.name as certificatename
  from certs as c
 cross join certdesc as cd 
 where cd.version = c.version
   and cd.name = c.name
 order by c.workerid
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜