考虑这个架构
CREATE TABLE [PrimaryTable]
[Id] int IDENTITY(1,1) NOT NULL
ALTER TABLE [PrimaryTable]
ADD CONSTRAINT [PK_PrimaryTable]
PRIMARY KEY ([Id])
CREATE TABLE [SecondaryTable]
[PrimaryTableId] int NOT NULL
[Name] nvarchar(4000) NOT NULL
[Value] nvarchar(4000) NULL
ALTER TABLE [SecondaryTable]
ADD CONSTRAINT [PK_SecondaryTable]
PRIMARY KEY ([PrimaryTableId],[Name])
然后是以下数据
PrimaryTable
| Id |
| 1 |
| 2 |
| 3 |
SecondaryTable
| PrimaryTableId | Name | Value |
| 1 | xxx | yyy |
| 2 | xxx | zzz |
我正在尝试编写一个查询,该查询将为PrimaryTable
中的所有条目提供xxx=yyy
的名称/值,包括SecondaryTable
中没有条目的条目} xxx
目前我有以下内容仅返回ID = 2,而不是ID = 3
SELECT Id FROM PrimaryTable
LEFT OUTER JOIN SecondaryTable ON PrimaryTable.Id = SecondaryTable.PrimaryTableId
WHERE (SecondaryTable.Name = 'xxx' AND SecondaryTable.Value NOT LIKE 'yyy')
用简单的英语描述附加条款将与...OR SecondaryTable.Name = 'xxx' does not exist
修改
我应该注意到,我已经简化了表格结构和此问题的查询 - PrimaryTable
中的其他列也将被检索(以及构成查询的一部分),并且{{{}}还有其他查询。 1}}使用不同的名称/值组合,以及不同的运算符(=,!=,LIKE,NOT LIKE)
(环境是SQL Server LocalDb 2014)
答案 0 :(得分:1)
我只是在连接表上添加了一个空检查,因此将包含该值。
SELECT Id
FROM PrimaryTable
LEFT OUTER JOIN SecondaryTable ON PrimaryTable.Id = SecondaryTable.PrimaryTableId
WHERE (
SecondaryTable.Name = 'xxx'
AND SecondaryTable.Value NOT LIKE 'yyy'
)
OR SecondaryTable.PrimaryTableId IS NULL
答案 1 :(得分:1)
使用NOT IN
SELECT Id
FROM PrimaryTable
WHERE Id NOT IN (
SELECT PrimaryTableId
FROM SecondaryTable
WHERE Name='xxx' AND Value='yyy')
使用NOT EXISTS
SELECT pt.Id
FROM PrimaryTable pt
WHERE NOT EXISTS (
SELECT *
FROM SecondaryTable st
WHERE pt.Id = pt.Id
AND (Name='xxx' AND Value='yyy')
答案 2 :(得分:0)
尝试:
SELECT Id
FROM
PrimaryTable
LEFT OUTER JOIN SecondaryTable ON
PrimaryTable.Id = SecondaryTable.PrimaryTableId
and (SecondaryTable.Name = 'xxx'
AND SecondaryTable.Value NOT LIKE 'yyy')
where
SecondaryTable.PrimaryTableId is null
这样就可以将数据过滤器子句移动到左连接上,并使用null检查列表工作的位置,就像在辅助表中不存在一样。
使用not exists的替代方案是:
select s.PrimaryTableId as Id
from
SecondaryTable s
where
not exists (select id from PrimaryTable where id = s.PrimaryTableId)
答案 3 :(得分:0)
尝试......
finally