好的。我已经设置了一小组样本表。我只是举个例子,因为这是我传达这个问题的最佳方式。
Certs表:
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表(版本,名称形式主键):
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.
现在。我想获得所有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)
此查询返回零行。问题是,无论版本号如何,都会排除拆除行。我想要的是使用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)
不幸的是,这在SQL Server中无效。有人知道一个很好的方法吗?
答案 0 :(得分: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
)
,或者,如果name
和version
足够,只需:
SELECT name, version
FROM CertDesc
EXCEPT
SELECT name, version
FROM Certs
WHERE WorkerId = 1
编辑:后一个查询仅适用于SQL-Server 2005。
答案 1 :(得分:0)
这样的事情会起作用吗?
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
比较:
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