SQL问题 - 同一个表中的一个名称2地址

时间:2011-02-11 20:32:26

标签: sql oracle

CName           |   AddressLine
-------------------------------
John Smith      | 123 Nowheresville
Jane Doe        | 456 Evergreen Terrace
John Smith      | 999 Somewhereelse
Joe Bloggs      | 1 Second Ave

如果我有这个表可以做一个像这样的选择

CNAME      | Address1           | Address2

John Smith | 123 Nowheresville  | 999 Somewhereelse

我正在使用oracle

4 个答案:

答案 0 :(得分:2)

在一些行中为重复的外观添加新列被认为是一种糟糕的设计(低效的内存使用)。也许您应该考虑使用内部联接和地址列的单独表格!

答案 1 :(得分: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

答案 2 :(得分:0)

temp =您的表名

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

答案 3 :(得分:0)

问题是解决,Frank 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

坦克向所有人寻求帮助