其中不存在子句被忽略

  • 本文关键字:子句 不存在 tsql
  • 更新时间 :
  • 英文 :


我正在尝试用应该存在的行填充表格:如果@Maps中的城市在@Results中不存在,那么我将使用NOT EXISTS填充它。问题是过滤器isused = 1不仅被忽略,而且似乎使NOT EXISTS无效

使用IsUsed = 1,@Maps中的所有内容都将插入到@Results中,无论它是否存在。

如果我删除IsUsed = 1,则插入纽约的两行(正确的行为,但不是我要找的(。

代码如下:

declare @Maps table
(
    Name varchar(20),
    IsUsed bit,
    Code varchar(20)
)
insert into @Maps
select 'NY', 1, 'NY1'
union select 'NY', 0, 'NY2'
union select 'FL', 0, 'FL1'
union select 'TX', 0, 'TX1'
declare @Results table 
(
    Name varchar(20),
    Value int,
    Code varchar(20)
)
insert into @results
select 'FL', 12, 'FL1'
union
select 'TX', 54,'TX1'
union
select 'CA', 54,'CA1'
union
select 'NJ', 54,'NJ1'
insert into @results
select Name, 999, code from @Maps m
-- This adds everything even if it exists
where not exists (select name from @Results p where p.name = m.name and IsUsed = 1)
-- This adds both 'NY'. Partially correct but adds column IsUsed = 0
-- where not exists (select name from @Results p where p.name = m.name)
select * from @results

如何添加未包含在@results中且 IsUse 等于 1 的一行?在这种情况下,它将是{'NY', 1, 'NY1 }'。

我知道有很多方法可以实现这一点,但我有兴趣了解not exists中的where子句是如何工作的。

您必须从NOT EXISTS中删除IsUsed=1并将其添加到WHERE

insert into @results
select Name, 999, code 
from @Maps m
where m.IsUsed = 1
and not exists (select name from @Results p where p.name = m.name)
我认为

您混淆了insert select的工作方式。 选择是独立运行的。 插入直到语句末尾才提交。 查看所有插入的 cnt 是 4。

declare @maps table(name varchar(10), isUsed bit, code varchar(10));
insert into @Maps values 
       ('NY', 1, 'NY1')
     , ('NY', 0, 'NY2')
     , ('FL', 0, 'FL1')
     , ('TX', 0, 'TX1')
declare @Results table (Name varchar(20), Value int, Code varchar(20), cnt int)
insert into @results values
       ('FL', 12, 'FL1', null)
     , ('TX', 54, 'TX1', null)
     , ('CA', 54, 'CA1', null)
     , ('NJ', 54, 'NJ1', null)
select * from @results;
insert into @Results
select m.Name, 999, m.code 
     , (select count(*) from @results) as cnt 
  from @Maps m 
 where not exists (select name 
                     from @Results p 
                    where p.name = m.name 
                      and m.IsUsed = 1) 
select * from @results;

在第一个纽约where p.name = m.name是假的not exits所以是真的

在第二个纽约where p.name = m.name是假的not exits所以是真的
第一个未提交的纽约

在 FL 和 TL 上,where p.name = m.name为真,但m.IsUsed = 1为假,因此not exits为真

最新更新