Oracle 10g 中的 LISTAGG 替代品
LISTAGG alternative in Oracle 10g
我是 Oracle 的新手。
卡在下面:
我有以下 2 个表格:
站点:
**SiteID|SiteName**
1 Sydney
2 Newyork
3 Delhi
人:
**RecordID|PeopleID|SiteID**
1 1 1
2 1 2
3 2 2
4 3 1
5 3 2
6 3 3
现在在我的查询中我想要这样的输出:
**PeopleID | AssignedSites**
1 Sydney,NewYork
2 Newyork
3 Sydney,NewYork,Delhi
- 还有几点:
-该解决方案应该也适用于 Oracle 10g 和 11g。
-我在上面的示例中为 brevity.But 提供了一小部分数据,在我的产品场景中,一个人可以与 1000 多个位置相关联,并且可能有 1000 多个这样的人,因此解决方案应该在那种情况下不会中断!
非常感谢任何帮助。
提前致谢。
尝试像这样使用 XMLAGG
:
select
p.PeopleID,
rtrim(xmlagg(xmlelement(e, s.SiteName, ',')).extract('//text()').getclobval(), ',')
from people p
join site s on p.SiteID = s.SiteID
group by p.PeopleID;
如果您需要按特定顺序串联,比如 SiteId 的递增顺序,则在 xmlagg 中添加一个 order by
子句:
select
p.PeopleID,
rtrim(xmlagg(xmlelement(e, s.SiteName, ',')
order by s.SiteId).extract('//text()').getclobval(), ',')
from people p
join site s on p.SiteID = s.SiteID
group by p.PeopleID;
编辑:
如果您想要显示分配到站点 100 的所有人员的结果:
select p.PeopleID,
rtrim(xmlagg(
xmlelement(e, s.SiteName, ',') order by s.SiteId
).extract('//text()').getclobval(), ',')
from people p
join site s on p.SiteID = s.SiteID
join (
select distinct PeopleID
from people
where siteID = 1
) p2 on p.PeopleID = p2.PeopleID
group by p.PeopleID;
listagg()
是显而易见的选择,但它在 Oracle 10 中不可用。但是,即使在 Oracle 11 中,listagg()
也仅限于长度为 4,000 的字符串,并且您明确地说“Person可以与 1000 多个位置关联。
有很多方法可以解决这个问题,使用 CLOB,XML,毫无疑问还有其他解决方案。但是,包含成千上万个字符的位置列表有什么用?由于位置如此之多,您将无法将结果放入标准 varchar2()
字段中。
也许以这种方式在数据库中汇总它们并不是解决您实际问题的最佳方案。
我想我已经接近成功了,只需要一点帮助:我创建了一个函数 GetSiteName,它 returns 网站名称与 SiteID 的对照。现在我正在使用下面的 xmlagg,我需要在其中调用此函数 GetSiteName:
select PeopleID, rtrim (xmlagg (xmlelement (e, clint.GetSiteName(SiteID) || ',')).extract ('//text()'), ',') SITEIDS
from client.People group by PeopleID;/
基本上需要帮助从 xmlagg 内部调用函数,有什么想法吗?
我只是需要一个 listagg on oracle 10g 的替代品,并在此页面中找到了一个 https://oracle-base.com/articles/misc/string-aggregation-techniques。
只需使用wm_concat,尽管它不受 oracle 支持并且已在 12c 中删除。
同上例:
select
p.PeopleID,wm_concat(s.SiteName)
from people p
join site s on p.SiteID = s.SiteID
group by p.PeopleID;
我是 Oracle 的新手。 卡在下面: 我有以下 2 个表格:
站点:
**SiteID|SiteName**
1 Sydney
2 Newyork
3 Delhi
人:
**RecordID|PeopleID|SiteID**
1 1 1
2 1 2
3 2 2
4 3 1
5 3 2
6 3 3
现在在我的查询中我想要这样的输出:
**PeopleID | AssignedSites**
1 Sydney,NewYork
2 Newyork
3 Sydney,NewYork,Delhi
- 还有几点:
-该解决方案应该也适用于 Oracle 10g 和 11g。
-我在上面的示例中为 brevity.But 提供了一小部分数据,在我的产品场景中,一个人可以与 1000 多个位置相关联,并且可能有 1000 多个这样的人,因此解决方案应该在那种情况下不会中断!
非常感谢任何帮助。
提前致谢。
尝试像这样使用 XMLAGG
:
select
p.PeopleID,
rtrim(xmlagg(xmlelement(e, s.SiteName, ',')).extract('//text()').getclobval(), ',')
from people p
join site s on p.SiteID = s.SiteID
group by p.PeopleID;
如果您需要按特定顺序串联,比如 SiteId 的递增顺序,则在 xmlagg 中添加一个 order by
子句:
select
p.PeopleID,
rtrim(xmlagg(xmlelement(e, s.SiteName, ',')
order by s.SiteId).extract('//text()').getclobval(), ',')
from people p
join site s on p.SiteID = s.SiteID
group by p.PeopleID;
编辑:
如果您想要显示分配到站点 100 的所有人员的结果:
select p.PeopleID,
rtrim(xmlagg(
xmlelement(e, s.SiteName, ',') order by s.SiteId
).extract('//text()').getclobval(), ',')
from people p
join site s on p.SiteID = s.SiteID
join (
select distinct PeopleID
from people
where siteID = 1
) p2 on p.PeopleID = p2.PeopleID
group by p.PeopleID;
listagg()
是显而易见的选择,但它在 Oracle 10 中不可用。但是,即使在 Oracle 11 中,listagg()
也仅限于长度为 4,000 的字符串,并且您明确地说“Person可以与 1000 多个位置关联。
有很多方法可以解决这个问题,使用 CLOB,XML,毫无疑问还有其他解决方案。但是,包含成千上万个字符的位置列表有什么用?由于位置如此之多,您将无法将结果放入标准 varchar2()
字段中。
也许以这种方式在数据库中汇总它们并不是解决您实际问题的最佳方案。
我想我已经接近成功了,只需要一点帮助:我创建了一个函数 GetSiteName,它 returns 网站名称与 SiteID 的对照。现在我正在使用下面的 xmlagg,我需要在其中调用此函数 GetSiteName:
select PeopleID, rtrim (xmlagg (xmlelement (e, clint.GetSiteName(SiteID) || ',')).extract ('//text()'), ',') SITEIDS
from client.People group by PeopleID;/
基本上需要帮助从 xmlagg 内部调用函数,有什么想法吗?
我只是需要一个 listagg on oracle 10g 的替代品,并在此页面中找到了一个 https://oracle-base.com/articles/misc/string-aggregation-techniques。
只需使用wm_concat,尽管它不受 oracle 支持并且已在 12c 中删除。
同上例:
select
p.PeopleID,wm_concat(s.SiteName)
from people p
join site s on p.SiteID = s.SiteID
group by p.PeopleID;