sql - 如何连接 SQL Server 中的多个列并在一个表中包含其他表中不存在的列?
问题描述
我有两个表,其架构与示例表 1 和示例表 2 相似。两个表都有用于标识两个表中的数据的列。A 列和 B 列在两个表中。
表格1:
Col A | Col B | Col C | Col D
--------+-------+-------+------
Cat 1 | Bla a | C-1 | D-1
Cat 1 | Bla a | C-2 | D-2
Cat 1 | Bla a | C-3 | D-3
Cat 2 | Bla b | C-4 | D-4
Cat 2 | Bla b | C-5 | D-5
表 2:
Col A | Col B | Col E
--------+-------+------
Cat 1 | Bla a | E-1
Cat 2 | Bla b | E-2
Cat 2 | Bla b | E-3
Cat 2 | Bla b | E-4
所需的输出表:
Col A | Col B | Col C | Col D | Col E
--------+-------+-------+-------+------
Cat 1 | Bla a | C-1 | D-1 | E-1
Cat 1 | Bla a | C-2 | D-2 | NULL
Cat 1 | Bla a | C-3 | D-3 | NULL
Cat 2 | Bla b | C-4 | D-4 | E-2
Cat 2 | Bla b | C-5 | D-5 | E-3
Cat 2 | Bla b | NULL | NULL | E-4
我需要组合、合并、更新、循环或以某种方式找到产生单个表的方法。在这个单个表中,我需要示例表 1 独有的列中的值与示例表 1 中的公共列值对齐。我还需要示例表 2 独有的列中的值与示例表 2 中的常用列值对齐。
如果一个表的公共列的匹配值比另一个表多,则唯一值应该为空,因为该记录成为其他唯一值的占位符。
表 1 在 A 和 B 列中有 3 条记录,其值为 Cat 1 和 Bla a。表 2 在 A 和 B 列中有 1 条记录,其值为 Cat 1 和 Bla a E 列的空值或空白值。
在我尝试执行联接或完全外部联接时,我得到了示例错误输出表中显示的结果。
所需输出表不应包含重复任一表中唯一值的值的记录。这显示在示例错误输出表中。
示例错误输出:
Col A | Col B | Col C | Col D | Col E
--------+-------+-------+-------+------
Cat 1 | Bla a | C-1 | D-1 | E-1
Cat 1 | Bla a | C-2 | D-2 | E-1
Cat 1 | Bla a | C-3 | D-3 | E-1
Cat 2 | Bla b | C-4 | D-4 | E-2
Cat 2 | Bla b | C-4 | D-4 | E-3
Cat 2 | Bla b | C-4 | D-4 | E-4
Cat 2 | Bla b | C-5 | D-5 | E-2
Cat 2 | Bla b | C-5 | D-5 | E-3
Cat 2 | Bla b | C-5 | D-5 | E-4
解决方案
declare @t1 table (
col_a varchar(5) null
,col_b varchar(5) null
,col_c varchar(5) null
,col_d varchar(5) null
)
declare @t2 table (
col_a varchar(5) null
,col_b varchar(5) null
,col_e varchar(5) null
)
insert into @t1 values
('Cat 1','Bla a','C-1','D-1')
,('Cat 1','Bla a','C-2','D-2')
,('Cat 1','Bla a','C-3','D-3')
,('Cat 2','Bla b','C-4','D-4')
,('Cat 2','Bla b','C-5','D-5')
insert into @t2 values
('Cat 1' , 'Bla a' , 'E-1' )
,('Cat 2' , 'Bla b' , 'E-2 ' )
,('Cat 2' , 'Bla b' , 'E-3' )
,('Cat 2' , 'Bla b' , 'E-4')
select isnull(a.col_a,b.col_a) col_a, isnull(a.col_b,b.col_b) col_b, a.col_c,a.col_d,b.col_e
from (
select *,row_number() over (partition by col_a order by col_c) rown
from @t1
) a
full outer join (
select *,row_number() over (partition by col_a order by col_e) rown
from @t2
) b
on a.col_a = b.col_a
and a.col_b = b.col_b
and a.rown = b.rown
order by isnull(a.col_a,b.col_a),isnull(a.rown,b.rown)
使用 row_number 作为完全连接的一部分是允许创建空值的原因。
推荐阅读
- python - 使用 pip 安装包后无法导入子包
- python - 如何打印 Locust 响应 (JSONDecodeError)
- javascript - Bokeh CustomJS 传递字形数组
- ruby-on-rails - 在 Ruby 中使用单个命令更新多条记录
- blockchain - 无法在节点和运行时之间转换参数“tx”:错误解码字段调用
- wix - 我需要从我的 wix 安装程序中删除功能选择屏幕
- java - PowerShell 中的 Java 问题“无法从 '14' 确定 java 版本”
- ubuntu-18.04 - 外接AV麦克风连接ubuntu
- phpstorm - PhpStorm 调试器从不输入代码,但在调试器运行时页面未完成加载
- python - 使用scrapy获取标签内的值