2016-02-27 85 views
1

我的表是這樣的:的Oracle 11g SQL合併兩行成一個(與條件)

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

您需要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反模式是這樣的。正如這個問題所顯示的那樣,你會花大部分時間試圖從信息中攫取信息。