如果列 x 是重复记录,则合并列 a、b、c - SQL

Posted

技术标签:

【中文标题】如果列 x 是重复记录,则合并列 a、b、c - SQL【英文标题】:Combine columns a, b, c if column x is duplicate record - SQL 【发布时间】:2015-12-15 22:00:06 【问题描述】:

我不确定我问的是否正确,但我试图让 1 行包含每个“政策”的所有数据。问题是,每行只给出 1 个“被保险人姓名”。

示例表:

我需要得到以下结果:

我该怎么做呢?

---编辑--- 如果只有一个被保险人,我希望被保险人名称 2 为 NULL

【问题讨论】:

您是要消除记录并将结果更改表结构和其中的数据结合起来,还是返回所需结果的视图/查询更符合您的需求? @anton 提出了一个很好的观点。如果同一保单下有超过 2 个被保险人,您希望在被保险人姓名 1 和被保险人 2 中使用什么名字? 不,我不想消除存在的记录。我只需要获取结果数据并将其导出到 .csv 文件。在这种情况下,可以有任意数量的被保险人。基本上,我只需要每个保单号码有 1 行,其中可以包含 x 个被保险人。最常见的是 1 或 2,但可能更多。 【参考方案1】:

我在查询中添加了生效日期,因为我可以看到一个包含保单编号和生效日期的复合主键。

这假设在更改现有表结构和数据时可以接受数据视图。

 SELECT a.PolicyNumber, a.effecitveDate a.insuredName as InsuredName1,   
        b.insuredName as InsuredName2
 FROM table a 
 INNER JOIN table b 
   ON a.policyNumber = b.policyNumber
  and A.effectiveDate = b.effectiveDate

请务必将table 更改为拥有此数据的tablename

此外,如果您想确保一种方式匹配只有and a.insuredName > B.InsuredName 加入。这是根据 j***s 的出色评论添加到这里的。

【讨论】:

对于有 2 名被保险人的保单,这会导致 InsuredName1 和 InsuredName2 列有 1 行具有相同名称 (John),然后是第二行,结果是我所追求的 ( InsuredName1 = John & InsuredName2 = Jane)。对于只有 1 名被保险人的保单,这会导致在 InsuredName1 和 InsuredName2 列中都有唯一被保险人的行。 你还需要 "and a.insuredName > b.insuredName" 否则你会得到 "John", "Jane" 和 "Jane", John" 在选择 InsuredName2 时,如果 InsuredName2 与 InsuredName1 匹配,我使用 case 语句将其设置为 NULL。感谢大家朝着正确的方向前进。 CASE WHEN b.insuredName <> InsuredName1 then b.InsuredName else null end as InsuredName2 @DustinN。 j***s 也有一个好主意,使用他的方法可以消除大小写的需要。 @xQbert 我已经尝试实现这一点,但是,它消除了 InsuredName2 为 NULL 的所有保单,因此它只返回有 2 个被保险人的保单【参考方案2】:

我相信您想以某种方式使用以下内容:

    SELECT DISTINCT a.insuredName, b.insuredName 
    FROM table a 
    INNER JOIN table b 
     ON a.policyNumber = b.policyNumber

如果生效日期也是一个考虑因素:

    ...
    On a.policyNumber = b.policyNumber
    And a.effectiveDate = b.effectiveDate;

【讨论】:

effectiveDate 也可能很重要(需要加入)。取决于表的键。我可以看到 Jon Doe 在 2015 年 1 月 1 日没有结婚,然后在 2015 年与 Jane 结婚,在 2016 年 1 月 1 日,她也采用了同样的政策。 是的。我也只是假设两个人是最大可能的共同被保险人。提供的数据确实如此,但不一定是经过案例编辑的答案。 你说得好……如果超过2个,我们如何选择被保险人? 你可以在 SELECT 子句中使用子查询,但它有点讨厌 或者也许多个连接与 wheres 以匹配所有保单持有人到相同的保单号码,但不是他们自己【参考方案3】:

由于您可以拥有无​​限数量的名称,因此我会将它们全部连接到一个列中,然后在加载时再次将其拆分。我不知道 Netezza,但这是你在 SQL Server 中的做法:

        SELECT PolicyNumber,
               InsuredDate,  
               STUFF(
                    (
                     SELECT ';'+ a.Path 
                     FROM Insured a 
                     WHERE t.PolicyNumber = a.PolicyNumber 
                     FOR XML PATH('')
                    ),1,1,'')  AS InsuredNames
        FROM (SELECT PolicyNumber, 
                     MIN(InsuredDate) AS InsuredDate 
              FROM Insured 
              GROUP BY PolicyNumber) t

【讨论】:

我在尝试实现这个时遇到错误,上面写着“找到“XML”(在字符 170 处)期待 `READ'”。当然这与 Netezza 有关,经过快速搜索后,我无法找到有关错误的任何内容。不过我会继续努力。 您需要了解 Netezza 如何允许您连接来自不同行的项目。它可能不像 SQL Server 那样使用 XML。

以上是关于如果列 x 是重复记录,则合并列 a、b、c - SQL的主要内容,如果未能解决你的问题,请参考以下文章

与 Pandas 合并的重复列?

合并列时如何保留所有唯一的值组合?

INSERT INTO .. ON DUPLICATE KEY更新多行记录

EXCEL如何根据A列相同内容在B列进行合并?

比较包含重复项的2列excel

EXCEL表格里如何将2列内容合并为1列