2014-06-17 49 views
3

我的SQL非常生锈。我试图改变这个表:根据第三列中的类型代码将列拆分为两列

+----+-----+--------------+-------+ 
| ID | SIN | CONTACT | TYPE | 
+----+-----+--------------+-------+ 
| 1 | 737 | [email protected] | email | 
| 2 | 760 | 250-555-0100 | phone | 
| 3 | 737 | 250-555-0101 | phone | 
| 4 | 800 | 250-555-0102 | phone | 
| 5 | 850 | [email protected] | email | 
+----+-----+--------------+-------+ 

到这个表:

+----+-----+--------------+-------------+ 
| ID | SIN | PHONE  | EMAIL | 
+----+-----+--------------+-------------+ 
| 1 | 737 | 250-555-0101 | [email protected] | 
| 2 | 760 | 250-555-0100 |    | 
| 4 | 800 | 250-555-0102 |    | 
| 5 | 850 |    | [email protected] | 
+----+-----+--------------+-------------+ 

我写此查询:

SELECT * 
    FROM (SELECT * 
      FROM people 
     WHERE TYPE = 'phone') phoneNumbers 
     FULL JOIN (SELECT * 
        FROM people 
        WHERE TYPE = 'email') emailAddresses 
      ON phoneNumbers.SIN = emailAddresses.SIN; 

主要生产:

+----+-----+--------------+-------+------+-------+-------------+--------+ 
| ID | SIN | CONTACT | TYPE | ID_1 | SIN_1 | CONTACT_1 | TYPE_1 | 
+----+-----+--------------+-------+------+-------+-------------+--------+ 
| 2 | 760 | 250-555-0100 | phone |  |  |    |  | 
| 3 | 737 | 250-555-0101 | phone | 1 | 737 | [email protected] | email | 
| 4 | 800 | 250-555-0102 | phone |  |  |    |  | 
| |  |    |  | 5 | 850 | [email protected] | email | 
+----+-----+--------------+-------+------+-------+-------------+--------+ 

我知道我可以选择我想要的列,bu SIN列不完整。我似乎记得,我应该第三次加入表格来获得完整的SIN列,但我不记得如何。

如何生成我的目标表(ID,SIN,PHONE,EMAIL)?

编辑和澄清:我非常感谢迄今为止收到的答案,但作为一个SQL新手,我不熟悉您正在使用的技术(case语句,条件聚合和透视)。这不能使用JOIN和SELECT来完成吗?请原谅我对这件事的无知。 (这并不是说我不感兴趣的卓越技术,但我不想太快太早移动。)接近,这是有条件的聚集

+0

我搞砸了这一段时间,唯一可以为此工作的其他事情将是多个UNIONs,这可能无法正常工作的情况下。最简单的选择是使用CASE,它只是SQL的IF循环。 – tsHunter

回答

3

方式一:

select min(ID), SIN, 
     max(case when type = 'phone' then contact end) as phone, 
     max(case when type = 'email' then contact end) as email 
from people t 
group by sin; 
1

似乎是一个pivot(神谕.com)在这里很容易工作。

SELECT ID, SIN, PHONE, EMAIL 
FROM PEOPLE 
PIVOT (
    MAX(CONTACT) 
    FOR TYPE IN ('EMAIL', 'PHONE') 
) 
0

我意识到这是比张贴的所有解决方案不太优雅,但在这里它是无论如何,只使用JOIN,然后选择一个解决方案:

SELECT sins.SIN, phone, email 
    FROM ((SELECT SIN email_sin, contact email 
      FROM people 
      WHERE TYPE = 'email') email 
     FULL JOIN (SELECT SIN phone_sin, contact phone 
        FROM people 
        WHERE TYPE = 'phone') phone 
      ON email.email_sin = phone.phone_sin) 
     RIGHT JOIN (SELECT DISTINCT SIN FROM people) sins 
      ON sins.SIN = phone_sin OR sins.SIN = email_sin; 

这缺少ID列。