当列不共享任何参数(包括主键)时,如何在 MS SQL Server 中进行 FULL OUTER JOIN?

Posted

技术标签:

【中文标题】当列不共享任何参数(包括主键)时,如何在 MS SQL Server 中进行 FULL OUTER JOIN?【英文标题】:How to do FULL OUTER JOIN in MS SQL Server when columns don't share any parameter including primary key? 【发布时间】:2020-09-12 01:44:47 【问题描述】:

我有很多表(我们称它们为单参数表),其中包括 ID(主键)和另一个参数(每个表中有 2 列)。我希望将所有这些加入到一个由 ID 和 param_1、param_2、....、param_n 列组成的joined_table 中。对于 ID 列(主键),joined_table 不是 NULL,其他列是 Nullable。 当参数共享ID值时,我可以正常进行FULL OUTER JOIN,没有问题。但是当一个参数不与任何其他参数共享主键时,我就会遇到问题。 简单地说,假设对于 ID 124,第三个单参数表中的 param_3 有一些值,但在其他单参数表中没有其他出现和值。

我的代码如下:

Insert into [joined_table]

(ID, param_1,param_2,param_3)

SELECT
       ID
      ,param1
      ,param2
      ,param3

FROM 
(
  SELECT 
        -- here if I write just "A.ID as ID" I will receive error of unfilled primary key column)
        COALESCE( A.ID, B.ID, C.ID) as ID 
        , A.param_1    as param1
        , B.param_2    as param2
        , C.param_3    as param3
  FROM 
     (
        (SELECT ID, param_1  FROM single_param_table_1) A

        FULL OUTER JOIN
        (SELECT IِِD, param_2  FROM single_param_table_2) B on A.ID= B.ID

        FULL OUTER JOIN 
        (SELECT ID, param_3 FROM single_param_table_3) C on A.ID = C.ID
        -- or:
        -- ISNULL(A.ID, B.ID)= C.ID
     )  

) as joined ;

我收到的错误信息如下:

Violation of PRIMARY KEY constraint 'PK_joined_table'. Cannot insert duplicate key in object 'joined_table'.

参数 3 似乎与其他参数没有完全分开,如果它共享密钥,则会尝试将重复的行插入到表中。

理想情况下,我希望得到 join_table 的结果:

 ID  |  param 1  |  param 2  |  param 3
=======================================
123  |    11     |    12     |   NULL
---------------------------------------
124  |   NULL    |   NULL    |    23

【问题讨论】:

选择所有可能的 ID 并将其加入您当前的查询(您应该使用分组排除重复项)。 @Iraj 。 . .您的问题不在于缺少 id 时。您的问题是 joined_table 中已经有行,或者一个或多个表有重复。 @Arvo 感谢您的回复。左连接有助于避免错误,但是我不会有任何与最后一列相关的条目(与其他参数不共享任何公共主键的列/参数) @GordonLinoff 谢谢!你救了我。问题在于最后一个 single_param_table 中有一个重复的 ID。我在我的选择语句中使用了 distinct,现在它已经解决了。 select distinct coalesce(t1.id, t2.id, t3.id, t4.id, . . . ) as id 这能回答你的问题吗? Strange duplicate behavior from GROUP_CONCAT of two LEFT JOINs of GROUP_BYs 【参考方案1】:

您的问题是一个或多个表有重复。

与此同时,您的 FULL JOIN 逻辑正在过滤掉您似乎想要的行。您可以简化和改进逻辑:

select coalesce(t1.id, t2.id, t3.id, t4.id, . . . ) as id,
       t1.param as param1,
       t2.param as param2,
       t3.param as param3,
       t4.param as param4,
       . . .
from single_param_table_1 t1 full join
     single_param_table_2 t2
     on t2.id = t1.id full join
     single_param_table_3 t3
     on t3.id = coalesce(t1.id, t2.id) full join
     single_param_table_4 t4
     on t4.id = coalesce(t1.id, t2.id, t3.id) full join
     . . .

也就是说,您需要大量使用coalesce(),以便ids 在表中匹配。

我应该注意到标准 SQL 和大多数数据库都支持 using 子句,它简化了这个逻辑。但是,SQL Server 不支持using

这简化了您的逻辑。但是,您的问题是一个或多个表具有重复的 ID。

【讨论】:

感谢您的回复。我实现了它,不幸的是仍然得到同样的错误。如果我使用 LEFT JOIN 而不是 FULL JOIN,我不会出错,但是当最后一个参数为 NULL 并且没有最后一个参数的值的行时,joined_table 结果将只包含第一个参数。 更新:我在选择ID之前添加了“distinct”,问题解决了! select distinct coalesce(t1.id, t2.id, t3.id, t4.id, . . . ) as id,谢谢。 @Iraj 。 . .您在基础表中有重复项。如果select distinct 有效,则重复项对于另一列具有相同的值。 谢谢。是的,我在其中一个基础表中有重复项。 “不同”有助于跳过重复项。它可能只选择该重复 ID 的第一个条目。这有什么问题吗?如果它删除重复的 ID 我很好(无论其他参数的值是什么) @Iraj 。 . .没问题——除非你应该弄清楚为什么会有重复,如果有问题就修复它。我的评论是,不仅id 重复,而且id/param 重复。

以上是关于当列不共享任何参数(包括主键)时,如何在 MS SQL Server 中进行 FULL OUTER JOIN?的主要内容,如果未能解决你的问题,请参考以下文章

在毫秒访问中自动上传 csv 数据,并包括自动编号主键 ID 字段

当列数据类型为列表时如何过滤熊猫数据框

如何在 AWS REDSHIFT 中使现有列不为空?

如何在 MS Access 中定义复合键?

如何使 s-s-rs 矩阵中的列不可见

SQL SERVER中索引类型包括的三种类型分别是哪三种?