2011-02-11 18 views
2
CName   | AddressLine 
------------------------------- 
John Smith  | 123 Nowheresville 
Jane Doe  | 456 Evergreen Terrace 
John Smith  | 999 Somewhereelse 
Joe Bloggs  | 1 Second Ave 

如果我有這個表可以做一個選擇把這樣SQL問題 - 一個名字在同一表2個地址

CNAME  | Address1   | Address2 

John Smith | 123 Nowheresville | 999 Somewhereelse 

我使用的是Oracle

+1

哪個數據庫? – Gerrat 2011-02-11 20:35:57

+1

如果你有3個或更多? – 2011-02-11 20:36:13

+0

@user - 每個`CName`最多有2個AddressLines?你怎麼知道哪個是1,哪個是2,還是這是隨意的? – 2011-02-11 20:36:34

回答

1

正如您的表格所示,您不能使用簡單的自聯接來將其減少爲單行。您可以將帶有所有地址的行(只要您爲特定的最大數量的地址進行硬編碼),但您將始終具有與給定用戶的地址相同的行數(除非您擁有一種將單個地址標識爲「主要」的方式)。

爲了減少你的結果集到一行,你必須提供一些標記「第一個」地址的方法。在SQL Server(或相近專業級的RDBM的),你可以使用一個公用表表達式與排名/行編號函數來做到這一點:

with Addresses as 
(select 
    CName, 
    AddressLine, 
    row_number() over (partition by CName order by AddressLine) as RowNum 

from YourTable) 
select 
    a1.CName, 
    a1.AddressLine as Address1, 
    a2.AddressLine as Address2, 
    a3.AddressLine as Address3 

from Addresses a1 

left join Addresses a2 on a2.CName = a1.CName and a2.RowNum = 2 
left join Addresses a3 on a3.CName = a1.CName and a3.RowNum = 3 

where a1.RowNum = 1 
0

溫度=

select distinct cname, addressline as [address1], 
( 
ISNULL((select addressline from temp where cname = t.cname and addressline != t.addressline), '') 
) as address2 
from 
temp t 
2

它被認爲是一個不好的設計(低效率的內存使用情況)你的表名添加一個新列重複的外觀只需S青梅竹馬。也許你應該考慮在地址欄中使用inner-join和一個單獨的表格!

0

的問題解決,弗蘭克Kulash在Oracle論壇解決了這個問題

這裏是解決方案:

WITH got_r_num AS 
(
    SELECT cname, addressline 
    , ROW_NUMBER() OVER (PARTITION BY cname 
         ORDER BY  addressline 
        )  AS r_num 
    FROM table_x 
-- WHERE ...  -- If you need any filtering, put it here 
) 
SELECT cname 
,  MIN (CASE WHEN r_num = 1 THEN addressline END) AS addressline1 
,  MIN (CASE WHEN r_num = 2 THEN addressline END) AS addressline2 
FROM  got_r_num 
GROUP BY cname 

坦克所有的幫助