SQL连接和输出格式

时间:2011-12-20 05:29:52

标签: sql oracle plsql oracle10g

任何人都可以帮我解决下面的SQL吗?

**Table A**

Id  Seq   First_Name    Last_Name
1   1     John          Walter 
1   2     Michael       Jordan
1   3     Sally         May  

我希望我的输出看起来像下面给定Id的位置,对于每个序列号,我想获得其他序列号的名字和姓氏。

示例输出

Id  Seq   Name
1   1     Michael Jordan | Sally May 
1   2     John Walter | Sally May
1   3     John Walter | Michael Jordan

有关SQL的任何帮助吗?

2 个答案:

答案 0 :(得分:2)

您想使用collect()聚合函数。

这是指向Oracle documentation的链接。

对于您的情况,这将是:

create or replace type names_t as table of varchar2(50);
/

create or replace function join_names(names names_t) 
                  return   varchar2
as
  ret varchar2(4000);
begin
  for i in 1 .. names.count loop

      if i > 1 then
         ret := ret || ',';
      end if;
      ret := ret || names(i);

  end loop;

  return ret;
end join_names;
/


create table tq84_table (
  id         number,
  seq        number,
  first_name varchar2(20),
  last_name  varchar2(20)
);

insert into tq84_table values (1, 1, 'John'   ,  'Walter');
insert into tq84_table values (1, 2, 'Michael',  'Jordan');
insert into tq84_table values (1, 3, 'Sally'  ,  'May'   );


select
  t1.id,
  t1.seq,
  join_names(
           cast(collect(t2.first_name || ' ' || t2.last_name order by t2.seq)
                as names_t)
  )
from
  tq84_table t1,
  tq84_table t2
where
  t1.id   =  t2.id and
  t1.seq !=  t2.seq
group by t1.id, t1.seq

如果您使用的是Oracle 11R2或更高版本,也可以使用 LISTAGG,这更简单(没有必要) 创建类型功能):

然后查询变为

select listagg(t2.first_name || ' ' || t2.last_name, ',') 
       within group (order by t2.seq)
         over (partition by id) as names
  from .... same as above ...

答案 1 :(得分:-2)

不仅适用于3列。这是一般情况。

 DECLARE @Names VARCHAR(8000)
SELECT @Names = COALESCE(@Names + ', ', '') + First_Name +' '+Last_Name FROM A
WHERE Seq !=2 and Id IS NOT NULL
select Id,Seq,@Names from A where Seq = 2
print @Names

您需要传递Seq值才能获取记录。 谢谢, 普里马