将多个表连接到数组列上

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

Join multiple table on array column

问题

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

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

  1. select
  2. tr.report_id,
  3. tr.sponsor_ids,
  4. array_agg(tsp.sponsor)
  5. --from public.tbl_report_page trp
  6. from public.tbl_report tr --on trp.report_id = tr.report_id
  7. left join public.tbl_sponsor tsp on tsp.sponsor_id = any(tr.sponsor_ids)
  8. --left join public.tbl_tag tg on tg.tag_id = any(tr.tags)
  9. group by tr.report_id,tr.sponsor_ids--,trp.page_id
  10. having tr.report_id = 109

这个工作正常,

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

但是当我取消注释

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

在赞助商中获取了许多值

  1. 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

  1. select
  2. tr.report_id,
  3. tr.sponsor_ids,
  4. array_agg(tsp.sponsor)
  5. --from public.tbl_report_page trp
  6. from public.tbl_report tr --on trp.report_id = tr.report_id
  7. left join public.tbl_sponsor tsp on tsp.sponsor_id = any(tr.sponsor_ids)
  8. --left join public.tbl_tag tg on tg.tag_id = any(tr.tags)
  9. group by tr.report_id,tr.sponsor_ids--,trp.page_id
  10. 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

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

getting lots of values in sponsors

  1. 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

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

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

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

  1. SELECT tr.report_id
  2. , tr.sponsor_ids
  3. , sp.sponsors
  4. , sp.tags
  5. FROM public.tbl_report tr
  6. LEFT JOIN LATERAL (
  7. SELECT array_agg(DISTINCT tsp.sponsor) AS sponsors
  8. , array_agg(DISTINCT tg.tag) AS tags
  9. FROM public.tbl_sponsor tsp
  10. LEFT JOIN public.tbl_tag tg ON tg.tag_id = ANY (tr.tags)
  11. WHERE tsp.sponsor_id = ANY (tr.sponsor_ids)
  12. ) sp ON true
  13. 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:

  1. SELECT tr.report_id
  2. , tr.sponsor_ids
  3. , sp.sponsors
  4. , sp.tags
  5. FROM public.tbl_report tr
  6. LEFT JOIN LATERAL (
  7. SELECT array_agg(DISTINCT tsp.sponsor) AS sponsors
  8. , array_agg(DISTINCT tg.tag) AS tags
  9. FROM public.tbl_sponsor tsp
  10. LEFT JOIN public.tbl_tag tg ON tg.tag_id = ANY (tr.tags)
  11. WHERE tsp.sponsor_id = ANY (tr.sponsor_ids)
  12. ) sp ON true
  13. 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:

确定