Oracle 11g SQL将两行合并为一行(带条件)

时间:2016-02-27 16:33:56

标签: sql oracle oracle11g

我的表格如下:

CONTACT
ID
---
1
2

CONTACTINFO
ID    |   CONTACT_ID    |   CONTACTINFOTYPE_ID    |   INFO
-------------------------------------------------------------
1     |   1             |    1                     |   'Herbert'
2     |   2             |    2                     |   'Berg'
3     |   2             |    1                     |   'Peter'
4     |   1             |    2                     |   'Gruber'
5     |   1             |    3                     |   '303-020-303'

CONTACTINFOTYPE
 ID    |   NAME
 ---------------
 1     |   'firstname'          
 2     |   'lastname'    
 3     |   'phonenumber'

这应该是我尝试创建的SQL代码的结果:

id | full name
---------------------
1  | Herbert Gruber
2  | Peter Berg

我当前的SQL代码如下所示

SELECT c.id AS id, 
case when cIT.name='firstname' then cI.info end
||' '||
case when cIT.name='lastname' then cI.info end AS fullname
FROM Contact c 
JOIN ContactInfo cI ON cI.Contact_Id=c.id 
JOIN ContactInfoType cIT ON cI.ContactInfoType_id=cIT.id;

结果是:

id | full name
---------------------
1  | Herbert
2  | Berg
2  | Peter
1  | Gruber

我已经尝试了其他一些方法,但它们似乎也无法工作。

1 个答案:

答案 0 :(得分:1)

您需要GROUP BY才能在同一行上获取匹配的项目。聚合函数可以是MAXMIN;我和MAX在一起了。此查询将为您提供ID,名字和姓氏

SELECT
  c.id AS id,
  MAX(CASE WHEN cIT.Name = 'firstname' THEN cI.Info END) AS FirstName,
  MAX(CASE WHEN cIT.Name = 'lastname' THEN cI.Info END) AS LastName
FROM Contact c
JOIN ContactInfo cI ON cI.Contact_Id=c.id
JOIN ContactInfoType cIT ON cI.ContactInfoType_id=cIT.id
GROUP BY c.id;

我想不出能够一次性连接名字和姓氏的方法,但我可以在这里忽略一些简单的东西。我能想到的最好的方法是使用上面的查询作为子查询或公用表表达式(CTE)。这是CTE方法,我发现它更干净,但使用您喜欢的方法。

WITH IDInfo AS (
  SELECT
    c.id AS id,
    MAX(CASE WHEN cIT.Name = 'firstname' THEN cI.Info END) AS FirstName,
    MAX(CASE WHEN cIT.Name = 'lastname' THEN cI.Info END) AS LastName
  FROM Contact c
  JOIN ContactInfo cI ON cI.Contact_Id=c.id
  JOIN ContactInfoType cIT ON cI.ContactInfoType_id=cIT.id
  GROUP BY c.id
)
SELECT id, FirstName || ' ' || LastName AS "full name"
FROM IDInfo;

我强烈建议不要使用像这样的God Table反模式。正如这个问题所显示的那样,你将花费大部分时间来尝试从中获取信息。