繁体   English   中英

SELECT语句中的DB2 SQL合并行

[英]DB2 SQL Merge Rows in SELECT statement

我有以下查询,我想为其合并BusinessPhone,传真,手机号码,电子邮件的行。 目前,这些结果在单独的行中返回。 我该如何实现?

SELECT DISTINCT
ABAN8 as AddressNumber,
(CASE WHEN TRIM(ALADD2)!='' THEN CONCAT(CONCAT(TRIM(ALADD1),', '),(CASE WHEN     TRIM(ALADD3)!='' THEN CONCAT(CONCAT(TRIM(ALADD2),', '),(CASE WHEN TRIM(ALADD4)!='' THEN CONCAT(CONCAT(TRIM(ALADD3),', '), TRIM(ALADD4)) ELSE TRIM(ALADD3) END)) ELSE TRIM(ALADD2) END)) ELSE TRIM(ALADD1) END) AS Address,
TRIM(ALCTY1) as City,
TRIM(ALCOUN) as Country,
TRIM(ALADDZ) as PostCode,
TRIM(ABALPH) as Company,
TRIM(WWATTL) as JobTitle,
TRIM(WWGNNM) as FirstName,
TRIM(WWSRNM) as Surname,
CASE WHEN WPPHTP = 'COM' THEN WPPH1 END BusinessPhone,
CASE WHEN WPPHTP = 'FACS' THEN WPPH1 END AS FAX,
CASE WHEN WPPHTP = 'MOB' THEN WPPH1 END AS MobileNumber,
CASE WHEN WPPHTP = 'HOME' THEN WPPH1 END AS HomePhone,
CASE WHEN WPPHTP = 'EML' THEN WPPH1 END AS EmailAddress
FROM CLTDTA.F0101 
LEFT OUTER JOIN CLTDTA.F0111 ON ABAN8 = WWAN8 
LEFT OUTER JOIN CLTDTA.F0115 ON ABAN8 = WPAN8
LEFT OUTER JOIN CLTDTA.F0116 ON ABAN8 = ALAN8
WHERE 
(CLTDTA.F0101.ABAT1 = 'ST' OR CLTDTA.F0101.ABAT1 = 'SC')

要解决这一问题,您需要玩联接游戏。 首先,我将基于您的示例查询进行以下假设:

  • F0101表的主键是地址号(ABAN8)。 它是独一无二的。
  • 每种地址类型(“ ST”或“ SC”)都有其自己的唯一地址号(ABAN8)。
  • 每个地址编号值只需要一行。
  • 电话号码和电子邮件地址存储在F0115中。 F0101和F0115之间存在一对多关系。
  • 地址行存储在F0115中。 F0101和F0115之间存在一对一的关系。

通过F0101和F0115之间的一对多关系,简单的联接查询将导致返回多个地址记录:每个电话/电子邮件记录一个。 但是,如果我们更改联接以使其仅返回一行,并对每种电话类型进行单独的联接,则可以将电话号码(和电子邮件)视为一行中的单独字段。 因此,让我们删除ABAN8 = WPAN8上的LEFT OUTER JOIN CLTDTA.F0115并将其替换为五个联接:

LEFT OUTER JOIN CLTDTA.F0115 ON ABAN8 = WPAN8 AND WPPHTP = 'COM' AS COM115
LEFT OUTER JOIN CLTDTA.F0115 ON ABAN8 = WPAN8 AND WPPHTP = 'FACS' AS FAX115
LEFT OUTER JOIN CLTDTA.F0115 ON ABAN8 = WPAN8 AND WPPHTP = 'MOB' AS MOB115
LEFT OUTER JOIN CLTDTA.F0115 ON ABAN8 = WPAN8 AND WPPHTP = 'HOME' AS HOME115
LEFT OUTER JOIN CLTDTA.F0115 ON ABAN8 = WPAN8 AND WPPHTP = 'EML' AS EML115

请注意,如果某个地址没有特定的电话类型,则其中一些连接将失败,并返回空值。 这是正常现象,这是正常现象,这也是为什么我们使用左联接而不是内部联接的原因。

为了解决问题,我们将所有这些CASE替换为SELECT子句的一部分,并从相关联的连接中将它们替换为相关字段。 这就是在联接中使用表别名的原因,您必须能够指定要从以下哪个特定值中提取F0115的5个版本中的哪个:

COM115.WPPH1 AS BusinessPhone,
FACS115.WPPH1 AS FAX,
MOB115.WPPH1 AS MobileNumber,
HOME115.WPPH1 AS HomePhone,
EML115.WPPH1 AS EmailAddress

根据您的应用程序,如果返回空值是一个问题,则可以将每个WPPH1字段包装在IFNULL()函数中。 这是最终查询:

SELECT DISTINCT
    ABAN8 as AddressNumber,
    (CASE WHEN TRIM(ALADD2)!='' THEN CONCAT(CONCAT(TRIM(ALADD1),', '),(CASE WHEN     TRIM(ALADD3)!='' THEN CONCAT(CONCAT(TRIM(ALADD2),', '),(CASE WHEN TRIM(ALADD4)!='' THEN CONCAT(CONCAT(TRIM(ALADD3),', '), TRIM(ALADD4)) ELSE TRIM(ALADD3) END)) ELSE TRIM(ALADD2) END)) ELSE TRIM(ALADD1) END) AS Address,
    TRIM(ALCTY1) as City,
    TRIM(ALCOUN) as Country,
    TRIM(ALADDZ) as PostCode,
    TRIM(ABALPH) as Company,
    TRIM(WWATTL) as JobTitle,
    TRIM(WWGNNM) as FirstName,
    TRIM(WWSRNM) as Surname,
    IFNULL(COM115.WPPH1) AS BusinessPhone,
    IFNULL(FACS115.WPPH1) AS FAX,
    IFNULL(MOB115.WPPH1) AS MobileNumber,
    IFNULL(HOME115.WPPH1) AS HomePhone,
    IFNULL(EML115.WPPH1) AS EmailAddress
FROM CLTDTA.F0101 
LEFT OUTER JOIN CLTDTA.F0111 ON ABAN8 = WWAN8 
LEFT OUTER JOIN CLTDTA.F0115 ON ABAN8 = WPAN8 AND WPPHTP = 'COM' AS COM115
LEFT OUTER JOIN CLTDTA.F0115 ON ABAN8 = WPAN8 AND WPPHTP = 'FACS' AS FAX115
LEFT OUTER JOIN CLTDTA.F0115 ON ABAN8 = WPAN8 AND WPPHTP = 'MOB' AS MOB115
LEFT OUTER JOIN CLTDTA.F0115 ON ABAN8 = WPAN8 AND WPPHTP = 'HOME' AS HOME115
LEFT OUTER JOIN CLTDTA.F0115 ON ABAN8 = WPAN8 AND WPPHTP = 'EML' AS EML115
LEFT OUTER JOIN CLTDTA.F0116 ON ABAN8 = ALAN8
WHERE (CLTDTA.F0101.ABAT1 = 'ST' OR CLTDTA.F0101.ABAT1 = 'SC')

请参阅注释中的jarlh答案以获取解决方案。

您必须GROUP BY所有不是设置函数参数的选定列。 (并在CASE表达式上执行MAX。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM