How to render one to many relationships to XML with PostgreSQL

我们两清 提交于 2019-12-05 07:02:00

Try:

SELECT p.id as pack_id,
       XMLELEMENT(name taskgroup,
                  XMLATTRIBUTES(tg.id as id),
                  XMLAGG(XMLELEMENT(name task,
                         XMLATTRIBUTES(t.id as id)) as xml_task_group
FROM packages p
JOIN package_taskgroup pt ON p.id = pt.package_id
JOIN taskgroups tg on pt.taskgroup_id = tg.id
JOIN taskgroup_task tt on tg.id = tt.taskgroup_id
JOIN tasks t on tt.task_id = t.id
WHERE p.id = somePackageId 
GROUP BY p.id, tg.id

This will give you all the task groups for the p.id you specified.

Then:

SELECT XMLELEMENT(name package, 
                  XMLATTRIBUTES(pack_id as id),
                  XMLAGG(xml_task_group))
FROM (previous SELECT here)

This will give you the structure you specified.

Details: XMLAGG, XML functions

Joined select will look like this:

SELECT XMLELEMENT(name package, 
                  XMLATTRIBUTES(pack_id as id),
                  XMLAGG(xml_task_group))
FROM (SELECT p.id as pack_id,
             XMLELEMENT(name taskgroup,
                        XMLATTRIBUTES(tg.id as id),
                        XMLAGG(XMLELEMENT(name task,
                                          XMLATTRIBUTES(t.id as id)
                       ))) as xml_task_group
      FROM packages p
      JOIN package_taskgroup pt ON p.id = pt.package_id
      JOIN taskgroups tg on pt.taskgroup_id = tg.id
      JOIN taskgroup_task tt on tg.id = tt.taskgroup_id
      JOIN tasks t on tt.task_id = t.id
      WHERE p.id = somePackageId 
      GROUP BY p.id, tg.id) t
GROUP BY pack_id

I simply copied the first select into FROM clause of the second.

You can try like this:

SELECT 
     T0."Mail",
     T0."UserName", 
     (SELECT xmlagg(xmlelement(name Screens, 
                               XMLELEMENT(name "IN1_ID","IN1."ID"),
                               XMLELEMENT(name "IN1_Name", IN1."Name")
                              )
                    ) 
             FROM "Advertisement"."Screen" IN1 
             WHERE T0."ID" = IN1."PlatformID"
    ) AS Screens 
    FROM "Sales"."Platform" T0

XNL Output will be like this:

<screens>
   <IN1_PlatformID>14</IN1_PlatformID>
   <IN1_Name>My Name</IN1_Name>
</screens>
<screens>
   <IN1_PlatformID>15</IN1_PlatformID>
   <IN1_Name>My Name 2</IN1_Name>
</screens>

at c# side you need to insert a root node to read this.

var doc = new System.Xml.XmlDocument();
doc.LoadXml("<rows>" + row["Screens"].ToString() + "</rows>");

After that, you can convert to dataset to read screens data easily:

var xmlReader = new System.Xml.XmlNodeReader(doc);
var dataSet = new System.Data.DataSet();
dataSet.ReadXml(xmlReader);
foreach (System.Data.DataRow item in dataSet.Tables[0].Rows){
    ...
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!