[英]Single SQL Select for one-to-many relationship tables using delimiter in column - Oracle
I have two tables with one-to-many relationship. 我有两个表具有一对多关系。
Table Person: 表人:
Id_person Name
-----------------------
1 Jack Black
2 Joe White
Table Telephone: 台式电话:
Id_telephone Id_person Number Type
----------------------------------------
5 1 333222111 Mobile
6 1 444333222 Fax
7 2 555444333 Mobile
Desired result of SQL SELECT statement: SQL SELECT语句的期望结果:
Name Telephone_Numbers
---------------------------------------------
Jack Black Mobile: 333222111, Fax: 444333222
Joe White Mobile: 555444333
I found many answers to this question, but related to SQL Server, i have no idea how to accomplish this with Oracle Database 10g. 我找到了这个问题的许多答案,但是与SQL Server有关,我不知道如何使用Oracle Database 10g完成此任务。 I need to populate Gridview in ASP.NET with this result, so i want to use this SELECT statement with OracleCommand and ExecuteQuery().
我需要用此结果填充ASP.NET中的Gridview,所以我想将此SELECT语句与OracleCommand和ExecuteQuery()一起使用。
Thanks for any hints. 感谢您的任何提示。
in 11gR2 you may use listAgg 在11gR2中,您可以使用listAgg
with person as
(
select 1 id_person, 'Jack Black' FullName from dual
union all
select 2 id_person, 'Joe White' FullName from dual
)
, telephone as
(
select 5 id_telephone , 1 Id_person, 333222111 phone_Number , 'Mobile' phone_type from dual
union all
select 6 id_telephone , 1 Id_person, 444333222 phone_Number , 'Fax' phone_type from dual
union all
select 7 id_telephone , 2 Id_person, 555444333 phone_Number , 'Mobile' phone_type from dual
)
select person.FullName
,listagg(telephone.phone_type || ': ' || telephone.phone_number , ', ') within group (order by person.FullName ) personToPhone
from person
inner join
telephone
on person.id_person = telephone.id_person
group by person.FullName ;
FULLNAME PERSONTOPHONE
---------- -----------------------------------
Jack Black Fax: 444333222, Mobile: 333222111
Joe White Mobile: 555444333
Look at this question for other approaches: comma-separated list as a result of select statement in Oracle 查看此问题的其他方法: Oracle中select语句的结果,逗号分隔列表
EDIT 编辑
for 10g you may use XMLAgg 对于10克,您可以使用XMLAgg
with person as
(
select 1 id_person, 'Jack Black' FullName from dual
union all
select 2 id_person, 'Joe White' FullName from dual
)
, telephone as
(
select 5 id_telephone , 1 Id_person, 333222111 phone_Number , 'Mobile' phone_type from dual
union all
select 6 id_telephone , 1 Id_person, 444333222 phone_Number , 'Fax' phone_type from dual
union all
select 7 id_telephone , 2 Id_person, 555444333 phone_Number , 'Mobile' phone_type from dual
)
select person.FullName
,RTRIM(XMLAGG(XMLELEMENT(e,telephone.phone_type || ': ' || telephone.phone_number || ',')).EXTRACT('//text()'),',') AS TelephoneToType
from person
inner join
telephone
on person.id_person = telephone.id_person
group by person.FullName ;
FULLNAME TELEPHONETOTYPE
---------- ---------------------------------
Jack Black Mobile: 333222111,Fax: 444333222
Joe White Mobile: 555444333
(as Mark Baker did in the linked SO question) (就像Mark Baker在链接的SO问题中所做的那样)
Select P.Name
, 'Mobile: ' || Coalesce( Min( Case When T.Type = 'Mobile' Then Number End ),'' )
+ Coalesce( 'Fax: ' || Min( Case When T.Type = 'Fax' Then Number End ),'' )
From Person P
Join Telephone T
On T.Id_Person = P.Id_person
Group By P.Name
有可能的解决方案列表在这里
Had the same problem awhile back. 曾经有过同样的问题。 All of the answers that I found said to use listagg, but client uses 10g.
我发现的所有答案都说使用listagg,但是客户端使用10g。 Create this function.
创建此功能。 Function is not mine found online.
在网上找不到我的功能。
create or replace
FUNCTION column_concat
(
p_cursor sys_refcursor,
p_del VARCHAR2
) RETURN VARCHAR2
IS
l_value VARCHAR2(32767);
l_result VARCHAR2(32767);
BEGIN
LOOP
FETCH p_cursor INTO l_value;
EXIT WHEN p_cursor%notfound;
IF l_result IS NOT NULL THEN
l_result := l_result || p_del;
END IF;
l_result := l_result || l_value;
END LOOP;
RETURN l_result;
END column_concat;
use it in Select like so: 像这样在Select中使用它:
select pers.name Names, column_concat(cursor(SELECT tel.type ||':' || tel.telnumber FROM person per, telephone tel Where per.id_person = tel.id_person and tel.id_person = pers.id_person), ',' ) Telephone_Numbers from person pers;
This should work for you. 这应该为您工作。 If you are on 11g, there is a built in aggregate function LISTAGG which is easier:
如果您使用的是11g,则有一个内置的聚合函数LISTAGG,它更简单:
with data
as
(
select
p.id_person,
p.name,
t.type||': '||t.phone_number telephone_number,
row_number() over (partition by p.id_person order by t.type) rn,
count(*) over (partition by p.id_person) cnt
from
person p
inner join telephone t
on t.id_person = p.id_person
)
select
name,
ltrim(sys_connect_by_path(telephone_number,', '),', ') telephone_number
from data
where rn = cnt
start with rn = 1
connect by prior id_person = id_person and prior rn = rn-1
order by id_person
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.