2017-06-29 35 views
1

我想加入一个表到另一个,但是当没有匹配时,我想使用特定的字符串值匹配,而不是我知道会有匹配值。表连接时没有匹配,然后使用定义的字符串

例如,如果我用借这个结构

declare @A table (id int identity(1,1), category varchar(4)) 
declare @B table (category varchar(4), name varchar(10)) 

insert @A values ('AB') 
insert @A values ('AB') 
insert @A values ('AB') 
insert @A values ('AB') 
insert @A values ('AC') 
insert @A values ('AD') 

insert @B values ('AB', 'Fred') 
insert @B values ('AC', 'Bob') 
insert @B values ('else', 'Jane') 
insert @B values ('else', 'Mary') 

一个简单连接:

select a.id, a.category, b.category, b.name 
from @A a 
inner join @B b on a.category = b.category 

然后第5条记录将匹配,我会结束:

1 AB AB Fred 
2 AB AB Fred 
3 AB AB Fred 
4 AB AB Fred 
5 AC AC Bob 

但是,我想要做的是为最后一个没有匹配记录的记录我想替换c在“其他”,使其匹配表@B两个记录和表@A ategory“AD”回来为:

1 AB  AB  Fred 
2 AB  AB  Fred 
3 AB  AB  Fred 
4 AB  AB  Fred 
5 AC  AC  Bob 
6 else else Jane 
6 else else Mary 

UPDATE:

也可能有场合表@A不包含匹配记录,所以我不认为可以使用RIGHT JOIN,因为我不想从@B获取所有记录。例如,如果@A没有足够的“AC”的记录,只是包含:

insert @A values ('AB') 
insert @A values ('AB') 
insert @A values ('AB') 
insert @A values ('AB') 
insert @A values ('AB') 
insert @A values ('AD') 

那么输出将是:

1 AB  AB  Fred 
2 AB  AB  Fred 
3 AB  AB  Fred 
4 AB  AB  Fred 
5 AB  AB  Fred 
6 else else Jane 
6 else else Mary 

什么会的各种选项是返回正确的数据?

+0

为什么不在''B'表中'RIGHT JOIN',然后在'SELECT'语句中使用'ISNULL()'来显示'else'。我不太确定你在这里做什么。你也可以在你的连接语句中使用两个连接条件,比如'JOIN ON category = category OR IF NOT EXISTS ...' – EMUEVIL

+0

我不认为我可以正确连接,因为我不想要所有记录从@B(查看更新) – ca8msm

+0

那么,你是否希望它从B返回匹配A的所有内容以及B中包含'else'的所有内容? Bob如何用“AB”返回? –

回答

2

您可以使用RIGHT JOIN而不是INNER JOIN。这将给你表B中的所有行。

然后,我会改变你的查询参数,使用“b.category”而不是“a.category”,因为它不会总是匹配。

最后,当ID不匹配时,可以使用ISNULL()。

select a.id, ISNULL(a.category, b.category), b.category, b.name 
from @A a 
    RIGHT join @B b on a.category = b.category 

虽然您的a.ID仍然为空。如果你想在表A中有一个比ID的最大值还要多,你也可以这样做。

select ISNULL(a.id, (SELECT MAX(id) from @a)), ISNULL(a.category, b.category), b.category, b.name 
from @A a 
    RIGHT join @B b on a.category = b.category 

所以,如果你的更新,你指的是不只有B行,要么具有匹配的行中的还是有“其他”作为类别,那么你可以这样做:

select ISNULL(a.id, (SELECT MAX(id) from @a)), ISNULL(a.category, 
b.category), b.category, b.name 
from @A a 
    RIGHT join @B b on a.category = b.category 
where a.id is not null or b.category = 'else' 

但我不明白你如何得到“AB”作为他的类别的“鲍勃”。

结果:

1 AB  AB  Fred 
2 AB  AB  Fred 
3 AB  AB  Fred 
4 AB  AB  Fred 
5 else else Jane 
5 else else Mary 
+0

谢谢,这产生了我所要求的正确结果,但是我不认为我可以正确加入,因为我不希望所有记录来自@B(请参阅我对原始问题的更新) – ca8msm

+0

然后,您需要提供例如我的解决方案无法工作。否则,我不明白缺少什么。 –

+0

我在更新的问题 – ca8msm

0

你正在寻找Right Join如要填充表@B中的所有场景。

select a.id, ISNULL(a.category,b.category) category, b.category, b.name 
from @A a 
right join @B b on a.category = b.category 

输出:

id   category category name 
----------- -------- -------- ---------- 
1   AB  AB  Fred 
2   AB  AB  Fred 
3   AB  AB  Fred 
4   AB  AB  Fred 
5   AC  AC  Bob 
NULL  else  else  Jane 
NULL  else  else  Mary 
+0

由于缺少6的id,这不会返回正确的结果 – ca8msm

0

你必须加入@B两次。第一次“正常”,然后当b1为null且b2.category尚未加入“正常”连接时。就像这样:

declare @A table (id int identity(1,1), category varchar(4)) 
declare @B table (category varchar(4), name varchar(10)) 

insert @A values ('AB') 
insert @A values ('AB') 
insert @A values ('AB') 
insert @A values ('AB') 
insert @A values ('AC') 
insert @A values ('AD') 

insert @B values ('AB', 'Fred') 
insert @B values ('AC', 'Bob') 
insert @B values ('else', 'Jane') 
insert @B values ('else', 'Mary') 


select 
    a.id 
    , coalesce(b2.category, a.category) as category1 
    , coalesce(b2.category, b1.category) as category2 
    , coalesce(b2.name, b1.name) as name 
from @A a 
    left join @b b1 on a.category = b1.category 
    left join @b b2 on b1.category is null and b2.category not in (select 
                    a.category 
                   from @A a 
                    inner join @B b on a.category = b.category) 
0

为了也有ID,我建议这个解决方案:

select a.id, a.category, b.category, b.name 
from @A a 
inner join @B b on a.category = b.category 
union all 
select nomatch.id, b.category, b.category, b.name 
from (select a.id 
    from @A a 
    left join @B b on a.category = b.category 
    where b.category is null) nomatch 
join @b 
where b.category = 'else' 

我不能完全肯定语法但是这将是想法。

0
declare @A table (id int identity(1,1), category varchar(4)) 
    declare @B table (category varchar(4), name varchar(10)) 
    Declare @id int = 0 **--added line** 
    insert @A values ('AB') 
    insert @A values ('AB') 
    insert @A values ('AB') 
    insert @A values ('AB') 

insert @A values ('AC') 
insert @A values ('AD') 
SELECT @id = @@IDENTITY; **----added line** 
insert @B values ('AB', 'Fred') 
insert @B values ('AC', 'Bob') 
insert @B values ('else', 'Jane') 
insert @B values ('else', 'Mary') 

select a.category, b.category, b.name, 
case 
when a.ID IS not NULL then a.id 
else @id 
end as ID 
from @A a 
right join @B b on a.category = b.category  
相关问题