将多个表连接到数组列上

huangapple go评论58阅读模式
英文:

Join multiple table on array column

问题

我有许多要连接的表,其中一些具有作为数组的连接列,

当我尝试使用两个表时,它正常工作

select 
    tr.report_id,
    tr.sponsor_ids,
    array_agg(tsp.sponsor)
--from public.tbl_report_page trp
from  public.tbl_report tr --on trp.report_id = tr.report_id

left join public.tbl_sponsor tsp on tsp.sponsor_id = any(tr.sponsor_ids)

--left join public.tbl_tag tg on tg.tag_id = any(tr.tags)

group by tr.report_id,tr.sponsor_ids--,trp.page_id
having tr.report_id = 109

这个工作正常,

109 {1,2,3,4,5,6} "{sponsor_1,sponsor_2,sponsor_3,sponsor_4,sponsor_5,sponsor_6}"

但是当我取消注释

left join public.tbl_tag tg on tg.tag_id = any(tr.tags)

在赞助商中获取了许多值

109 {1,2,3,4,5,6} "{sponsor_1,sponsor_1,sponsor_1,sponsor_2,sponsor_2,sponsor_2,sponsor_3,sponsor_3,sponsor_3,sponsor_4,sponsor_4,sponsor_4,sponsor_5,sponsor_5,sponsor_5,sponsor_6,sponsor_6,sponsor_6}"

我必须添加更多包含ID的表作为数组。

英文:

I have many tables to join, some of them have joining columns as array,

When I tried with two tables it worked fine

select 
		tr.report_id,
		tr.sponsor_ids,
		array_agg(tsp.sponsor)
	--from public.tbl_report_page trp
	from  public.tbl_report tr --on trp.report_id = tr.report_id

	left join public.tbl_sponsor tsp on tsp.sponsor_id = any(tr.sponsor_ids)

	--left join public.tbl_tag tg on tg.tag_id = any(tr.tags)

	group by tr.report_id,tr.sponsor_ids--,trp.page_id
	having tr.report_id = 109

This works fine,

> 109 {1,2,3,4,5,6} "{sponsor_1,sponsor_2,sponsor_3,sponsor_4,sponsor_5,sponsor_6}"

but when I uncomment

left join public.tbl_tag tg on tg.tag_id = any(tr.tags)

getting lots of values in sponsors

109	{1,2,3,4,5,6}	"{sponsor_1,sponsor_1,sponsor_1,sponsor_2,sponsor_2,sponsor_2,sponsor_3,sponsor_3,sponsor_3,sponsor_4,sponsor_4,sponsor_4,sponsor_5,sponsor_5,sponsor_5,sponsor_6,sponsor_6,sponsor_6}"

I have to add more tables which contains ids as array.

答案1

得分: 1

首先,通常最好将这些数组替换为关系设计中的标准化多对多关系。参见:

如果你目前只能使用当前的设计,请考虑连接操作如何扩大行数:

你的查询可能像这样工作:

SELECT tr.report_id
     , tr.sponsor_ids
     , sp.sponsors
     , sp.tags
FROM   public.tbl_report tr
LEFT   JOIN LATERAL (
   SELECT array_agg(DISTINCT tsp.sponsor) AS sponsors
        , array_agg(DISTINCT tg.tag) AS tags
   FROM   public.tbl_sponsor tsp
   LEFT   JOIN public.tbl_tag tg ON tg.tag_id = ANY (tr.tags)
   WHERE  tsp.sponsor_id = ANY (tr.sponsor_ids)   
   ) sp ON true
WHERE  tr.report_id = 109;

根据你的实际目标,可能还有更多的优化可能。

保留数组项的原始顺序。参见:

相关链接:

英文:

For starters, it's typically superior to replace those arrays with normalized many-to-many relationships in your relational design. See:

While stuck with your current design, consider how joins can multiply rows:

Your query probably works like this:

SELECT tr.report_id
     , tr.sponsor_ids
     , sp.sponsors
     , sp.tags
FROM   public.tbl_report tr
LEFT   JOIN LATERAL (
   SELECT array_agg(DISTINCT tsp.sponsor) AS sponsors
        , array_agg(DISTINCT tg.tag) AS tags
   FROM   public.tbl_sponsor tsp
   LEFT   JOIN public.tbl_tag tg ON tg.tag_id = ANY (tr.tags)
   WHERE  tsp.sponsor_id = ANY (tr.sponsor_ids)   
   ) sp ON true
WHERE  tr.report_id = 109;

Depending on your actual objective, more optimization may be possible.

This does not preserve original order of array items. See:

Related:

huangapple
  • 本文由 发表于 2023年7月13日 17:42:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76677992.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定