针对具有NOT LIKE条件和值不存在的表的SQL连接

时间:2015-06-09 17:12:11

标签: sql sql-server

考虑这个架构

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)

4 个答案:

答案 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