如果列 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的主要内容,如果未能解决你的问题,请参考以下文章