【问题标题】:Can I combine 2 Json_agg queries into a single result?我可以将 2 个 Json_agg 查询组合成一个结果吗?
【发布时间】:2020-08-31 20:11:12
【问题描述】:

我有以下 2 个查询。我需要使用两个查询,因为第一个查询获取总匹配记录,第二个查询返回前 50 个结果。我想在一次调用中运行两个查询并将结果合并为一个结果?

如何将这两个结果合并为一个值?我已经尝试过 UNION,但这似乎不适用于 JSON 输出。

我正在使用 Postges 11

    select count(tbl_310.id)
    FROM 
    schema_1.tbl_310 tbl_310
    left join schema_1.tbl_310_customid custom on custom.id=tbl_310.id
    left join lateral (
          select distinct field_53.*
          from  schema_1.tbl_310_to_tbl_342_field_53 field_53
          where field_53.tbl_310_id=tbl_310.id
          limit 50) field_53 on true

          left join lateral (
              select distinct tbl_342.*
              from schema_1.tbl_342_customid tbl_342
              where tbl_342.id = field_53.tbl_342_id
              limit 50
          ) tbl_342 on true

     left join lateral (
      select distinct field_41_join.*
      from  schema_1.tbl_310_field_41_join field_41_join
      where field_41_join.id=tbl_310.id
      limit 50) field_41_join on true

      left join lateral (
          select distinct field_41.*
          from schema_1.tbl_310_field_41 field_41
          where field_41.optionid = field_41_join.optionid
          limit 5
      ) field_41 on true left join lateral (
      select distinct field_52_join.*
      from  schema_1.tbl_310_field_52_join field_52_join
      where field_52_join.id=tbl_310.id
      limit 50) field_52_join on true

      left join lateral (
          select distinct field_52.*
          from schema_1.tbl_310_field_52 field_52
          where field_52.optionid = field_52_join.optionid
          limit 5
      ) field_52 on true 
      WHERE 
      field_52.optionid = ANY (Array[1]) ;


  select array_to_json(array_agg(t)) from (
  select
  tbl_310.id,custom.fullname as "CustomID",tbl_310.field_42,tbl_310.field_16,tbl_310.field_1,tbl_310.field_2,tbl_310.field_44,tbl_310.field_8,tbl_310.field_45,tbl_310.id
  ,jsonb_agg(distinct jsonb_build_object('id',tbl_342.id,'data',tbl_342.fullname)) as field_53
  , jsonb_agg(distinct jsonb_build_object('optionid',field_41.optionid,'data',field_41.option,'attributes',field_41.attributes)) as field_41,jsonb_agg(distinct jsonb_build_object('optionid',field_52.optionid,'data',field_52.option,'attributes',field_52.attributes)) as field_52

  FROM
  schema_1.tbl_310 tbl_310
  left join schema_1.tbl_310_customid custom on custom.id=tbl_310.id
  left join lateral (
          select distinct field_53.*
          from  schema_1.tbl_310_to_tbl_342_field_53 field_53
          where field_53.tbl_310_id=tbl_310.id
          limit 50) field_53 on true

          left join lateral (
              select distinct tbl_342.*
              from schema_1.tbl_342_customid tbl_342
              where tbl_342.id = field_53.tbl_342_id
              limit 50
          ) tbl_342 on true

  left join lateral (
      select distinct field_41_join.*
      from  schema_1.tbl_310_field_41_join field_41_join
      where field_41_join.id=tbl_310.id
      limit 50) field_41_join on true

      left join lateral (
          select distinct field_41.*
          from schema_1.tbl_310_field_41 field_41
          where field_41.optionid = field_41_join.optionid
          limit 5
      ) field_41 on true left join lateral (
      select distinct field_52_join.*
      from  schema_1.tbl_310_field_52_join field_52_join
      where field_52_join.id=tbl_310.id
      limit 50) field_52_join on true

      left join lateral (
          select distinct field_52.*
          from schema_1.tbl_310_field_52 field_52
          where field_52.optionid = field_52_join.optionid
          limit 5
      ) field_52 on true

      WHERE 
  field_52.optionid = ANY (Array[1]) 
      GROUP BY tbl_310.id,custom.fullname,tbl_310.field_42,tbl_310.field_16,tbl_310.field_1,tbl_310.field_2,tbl_310.field_44,tbl_310.field_8,tbl_310.field_45,tbl_310.id
      ORDER BY tbl_310.id asc
      Limit 50
      ) t;

已更新尝试使用您的格式,但出现语法错误。 在这里看到任何问题?

 SELECT
          count(tbl_310.id) AS count,
          array_to_json((array_agg(t))[1:50]) AS array
          FROM
          select
          tbl_310.id,custom.fullname as "CustomID",tbl_310.field_42,tbl_310.field_16,tbl_310.field_1,tbl_310.field_2,tbl_310.field_44,tbl_310.field_8,tbl_310.field_45,tbl_310.id
          ,jsonb_agg(distinct jsonb_build_object('id',tbl_342.id,'data',tbl_342.fullname)) as field_53
          , jsonb_agg(distinct jsonb_build_object('optionid',field_41.optionid,'data',field_41.option,'attributes',field_41.attributes)) as field_41,jsonb_agg(distinct jsonb_build_object('optionid',field_52.optionid,'data',field_52.option,'attributes',field_52.attributes)) as field_52
          FROM
          schema_1.tbl_310 tbl_310
          left join schema_1.tbl_310_customid custom on custom.id=tbl_310.id
          left join lateral (
                  select distinct field_53.*
                  from  schema_1.tbl_310_to_tbl_342_field_53 field_53
                  where field_53.tbl_310_id=tbl_310.id
                  limit 50) field_53 on true
 
                  left join lateral (
                      select distinct tbl_342.*
                      from schema_1.tbl_342_customid tbl_342
                      where tbl_342.id = field_53.tbl_342_id
                      limit 50
                  ) tbl_342 on true
 
          left join lateral (
              select distinct field_41_join.*
              from  schema_1.tbl_310_field_41_join field_41_join
              where field_41_join.id=tbl_310.id
              limit 50) field_41_join on true
 
              left join lateral (
                  select distinct field_41.*
                  from schema_1.tbl_310_field_41 field_41
                  where field_41.optionid = field_41_join.optionid
                  limit 5
              ) field_41 on true left join lateral (
              select distinct field_52_join.*
              from  schema_1.tbl_310_field_52_join field_52_join
              where field_52_join.id=tbl_310.id
              limit 50) field_52_join on true
 
              left join lateral (
                  select distinct field_52.*
                  from schema_1.tbl_310_field_52 field_52
                  where field_52.optionid = field_52_join.optionid
                  limit 5
              ) field_52 on true
 
                  WHERE 
              field_52.optionid = ANY (Array[1]) 
                  GROUP BY tbl_310.id,custom.fullname,tbl_310.field_42,tbl_310.field_16,tbl_310.field_1,tbl_310.field_2,tbl_310.field_44,tbl_310.field_8,tbl_310.field_45,tbl_310.id
                  ORDER BY tbl_310.id asc
                  ) t

【问题讨论】:

  • 只使用 CTE?
  • 您可能需要显示每个查询的结果,以及最后想要的结果(作为表格文本)。
  • CTE 语法是什么样的?

标签: sql arrays json postgresql count


【解决方案1】:

CTE 会有所帮助:

WITH (… long and complicated query …) AS intermediate
SELECT
  (SELECT count(*) FROM intermediate) AS count,
  (SELECT json_agg(t) FROM intermediate t LIMIT 50) AS array;

或者,您可以使用已经构建的数组:

WITH (SELECT array_agg(t) AS arr FROM (… long and complicated query …) t) AS intermediate
SELECT
  array_length(arr, 1) AS count,
  array_to_json(arr[1:50]) AS array
FROM intermediate;

这可能甚至不需要 CTE 语法,而只需要一个子查询,甚至只是

SELECT
  count(*),
  array_to_json((array_agg(t))[1:50]) AS array
FROM (… long and complicated query …) t

【讨论】:

  • 我尝试使用您的格式,请参阅我更新的帖子...它给出了语法错误,但我看不到问题。我的格式有什么问题?
  • 我想括号不匹配,FROM …) t 中没有开头的(?我已经更新了我的答案,更清楚地使用了您的表别名 t
  • 太棒了,效果很好!在这种格式 [1:50] 上,是设置开始行,结束行吗?因此,我可以将其设置为我想要返回的任何子集,而不是使用偏移量和限制?所以要返回记录 100 到 200,它将是 [100:200]
  • 是的,这是array slice syntax。免责声明:我不知道这有多有效,它可能会将所有行收集到数组中。
  • hmm..ok,这将是一个性能问题。如果查询有数万行......我想最简单的解决方案是只运行 2 个单独的查询并将它们聚合到业务逻辑中。
猜你喜欢
  • 2016-10-05
  • 2015-04-04
  • 2015-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多