我有两个表,我想使用左外连接连接在一起.但是,即使我的左表只包含唯一值,右表也不止一次地满足CONDITION,因此会在结果集中添加额外的行.
代码复制问题:
declare @tb1 table (c1 int) declare @tb2 table (c2 int) INSERT INTO @tb1 VALUES (1) INSERT INTO @tb1 VALUES (2) INSERT INTO @tb1 VALUES (3) INSERT INTO @tb1 VALUES (4) INSERT INTO @tb2 VALUES (3) INSERT INTO @tb2 VALUES (4) INSERT INTO @tb2 VALUES (5) INSERT INTO @tb2 VALUES (6) select * from @tb1 left outer join @tb2 ON c1 = c2 INSERT INTO @tb2 VALUES (3) INSERT INTO @tb2 VALUES (4) INSERT INTO @tb2 VALUES (5) INSERT INTO @tb2 VALUES (6) select * from @tb1 left outer join @tb2 ON c1 = c2
正如您所看到的,第一个SELECT返回4行,其中第二个SELECT 6,尽管左表保持不变.
如何对左表保持严格,只使用右表来补充左表中的行?
救命!
RESULTS: c1 c2 ----------- ----------- 1 NULL 2 NULL 3 3 4 4 [DUPLICATE @tb2 records] c1 c2 ----------- ----------- 1 NULL 2 NULL 3 3 3 3 4 4 4 4
Tor*_*gen 14
对不起,但你的想法是扭曲的.
以这种方式思考:如果你只想从tb2为tb1中的每一行提供一行,那么服务器应该选择哪一行?事实是,从连接的定义来看,右侧表中与左侧行匹配的每一行都是匹配的,必须包含在内.
在连接之前,您必须确保tbl2具有不同的c2值.如果您的SQL变体支持DISTINCT [column](并非所有的话),Murph的建议可能会这样做.
如果您只想在左侧保留单行,则需要为左侧的每个唯一值决定要在右侧显示的内容。例如,如果您想显示计数,您可以这样做:
select b1.c1, x.c from @tb1 b1
left outer join
(
select c2, count(*) as c
from @tb2
group by c2
) as x
ON b1.c1 = x.c2
Run Code Online (Sandbox Code Playgroud)
或者如果您只想要 c2 中的值出现一次:
select b1.c1, x.c2 from @tb1 b1
left outer join
(
select c2
from @tb2
group by c2
) as x
ON b1.c1 = x.c2
Run Code Online (Sandbox Code Playgroud)
尝试使用
select DISTINCT * from @tb1 left outer join @tb2 ON c1 = c2
Run Code Online (Sandbox Code Playgroud)
嗯,查询正在执行其应该执行的操作,因为右侧表中有重复的记录(或至少有重复的标识符)。
为了达到你想要的效果:
SELECT * FROM @tb1 LEFT OUTER JOIN (SELECT DISTINCT c2 FROM @tb2) t2 ON @tb1.c1 = t2.c2
Run Code Online (Sandbox Code Playgroud)
如果这还不够,您需要更详细地解释要求。
| 归档时间: |
|
| 查看次数: |
36608 次 |
| 最近记录: |