简体   繁体   English

使用列中的定界符对一对多关系表进行单个SQL Select-Oracle

[英]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 Ba​​ker在链接的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.

相关问题 如何使用Entity Framework从具有一对多关系的两个表中选择所有相关数据? - How to select all related data from two tables having one-to-many relationship using Entity Framework? 单个SQL查询可处理多个一对多关系,并且仅输出一次结果 - A single SQL query to deal with more than one one-to-many relationship and output the results once only EF Core 2.1选择一对多关系的字段 - EF Core 2.1 Select fields for one-to-many relationship 使用SQL Server数据存储的实体框架为一对多关系建模 - Entity Framework using SQL Server datastore modelling a one-to-many relationship NHibernate-基于类型列的热切负载一对多关系 - NHibernate - Eager load one-to-many relationship on the basis of type column LINQ to SQL获得一对多表列结果作为数组 - LINQ to SQL get one-to-many table column result as array Nhibernate:无法映射一对多关系 - Nhibernate: Trouble mapping a one-to-many relationship 创建动作方法中的一对多关系 - One-to-many relationship in the create action method 一对多关系不编辑子表 - One-To-Many Relationship not editing Child table 使用实体框架在 ASP.NET MVC 中为具有一对多关系的数据库播种 - Seeding database with a one-to-many relationship in ASP.NET MVC using Entity Framework
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM