聚合函数调用不能嵌套 - 替代

时间:2017-06-05 00:07:31

标签: postgresql elixir ecto elixir-framework

PostgrSQL嵌套json_agg

我有这个问题:

  def create_unique_shop_query_no_keyword(categories, shop_ids) do
    products_shops_categories = from p in Product,
    join: ps in ProductShop, on: p.id == ps.p_id,
    join: s in Shop, on: s.id == ps.s_id,
    join: pc in ProductCategory, on: p.id == pc.p_id,
    join: c in Subcategory, on: c.id == pc.c_id,
    distinct: s.id,
    where: c.id in ^categories,
    where: s.id in ^shop_ids,
    group_by: [s.id, s.name],
    select: %{products: fragment("json_agg( DISTINCT (?, ?, ?, ?)) AS products", p.id, p.name, p.brand, p.image), categories: fragment("json_agg( DISTINCT (?, ?)) AS category", c.id, c.name), shop: fragment("json_agg( DISTINCT (?, ?, ST_X(?), ST_Y(?))) AS shop", s.id, s.name, s.point, s.point)}
  end

它将所有产品和类别都放在一个独特的商店中,但这些类别并未指向任何产品。现在我想修改它以获得所有产品在独特的商店,并在产品内,获得产品的类别。我尝试了一些变体:

  def create_unique_shop_query_no_keyword(categories, shop_ids) do
    products_shops_categories = from p in Product,
    join: ps in ProductShop, on: p.id == ps.p_id,
    join: s in Shop, on: s.id == ps.s_id,
    join: pc in ProductCategory, on: p.id == pc.p_id,
    join: c in Subcategory, on: c.id == pc.c_id,
    distinct: s.id,
    where: c.id in ^categories,
    where: s.id in ^shop_ids,
    group_by: [s.id, s.name],
    select: %{products: fragment("json_agg( DISTINCT (?, ?, ?, ?, json_agg( DISTINCT (?, ?)) AS categories)) AS products", p.id, p.name, p.brand, p.image, c.id, c.name), shop: fragment("json_agg( DISTINCT (?, ?, ST_X(?), ST_Y(?))) AS shop", s.id, s.name, s.point, s.point)}

所有人都收到此错误:

11:57:59.819 [error] #PID<0.341.0> running Api.Router terminated
Server: 192.168.20.3:4000 (http)
Request: GET /products?categories[]=1&categories[]=2&categories[]=3&categories[]=4&categories[]=5&categories[]=6&categories[]=7&ke
yword=&latitude=-36.8597515&longitude=174.7847599&distanceFromPlaceValue=1.0&distanceFromPlaceUnit=kilometer
** (exit) an exception was raised:
    ** (Postgrex.Error) ERROR 42803 (grouping_error): aggregate function calls cannot be nested
        (ecto) lib/ecto/adapters/sql.ex:436: Ecto.Adapters.SQL.execute_and_cache/7
        (ecto) lib/ecto/repo/queryable.ex:130: Ecto.Repo.Queryable.execute/5
        (ecto) lib/ecto/repo/queryable.ex:35: Ecto.Repo.Queryable.all/4
        (api) lib/api/router.ex:153: anonymous fn/1 in Api.Router.do_match/4
        (api) lib/api/router.ex:1: Api.Router.plug_builder_call/2
        (api) lib/plug/debugger.ex:123: Api.Router.call/2
        (plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
        (cowboy) /Users/Ben/Development/Projects/vepo/api/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4

这可以使用嵌套的json_agg吗?

将选择更改为:

select: %{products: fragment("json_agg( DISTINCT (?, ?, ?, ?, ?, ?)) AS products", p.id, p.name, p.brand, p.image, c.id, c.name), shop: fragment("json_agg( DISTINCT (?, ?, ST_X(?), ST_Y(?))) AS shop", s.id, s.name, s.point, s.point)}

有点做我想要的但是它为产品的每个类别选择一个新行,重复产品,例如这是一个独特的商店:

[%{products: [%{"f1" => 30, "f2" => "lollies", "f3" => "wonka ", "f4" => nil,
      "f5" => 1, "f6" => "Meat"},
    %{"f1" => 30, "f2" => "lollies", "f3" => "wonka ", "f4" => nil, "f5" => 2,
      "f6" => "Dairy"},
    %{"f1" => 30, "f2" => "lollies", "f3" => "wonka ", "f4" => nil, "f5" => 3,
      "f6" => "Confectionary"},
    %{"f1" => 31, "f2" => "peanut butter", "f3" => "kraft", "f4" => nil,
      "f5" => 5, "f6" => "Baking"},
    %{"f1" => 31, "f2" => "peanut butter", "f3" => "kraft", "f4" => nil,
      "f5" => 6, "f6" => "Condiments"},
    %{"f1" => 31, "f2" => "peanut butter", "f3" => "kraft", "f4" => nil,
      "f5" => 7, "f6" => "Beverages"},
    %{"f1" => 36, "f2" => "a", "f3" => "a", "f4" => nil, "f5" => 1,
      "f6" => "Meat"},
    %{"f1" => 36, "f2" => "a", "f3" => "a", "f4" => nil, "f5" => 2,
      "f6" => "Dairy"},
    %{"f1" => 36, "f2" => "a", "f3" => "a", "f4" => nil, "f5" => 3,
      "f6" => "Confectionary"},
    %{"f1" => 36, "f2" => "a", "f3" => "a", "f4" => nil, "f5" => 4,
      "f6" => "Dessert"},
    %{"f1" => 36, "f2" => "a", "f3" => "a", "f4" => nil, "f5" => 5,
      "f6" => "Baking"},
    %{"f1" => 36, "f2" => "a", "f3" => "a", "f4" => nil, "f5" => 6,
      "f6" => "Condiments"},
    %{"f1" => 36, "f2" => "a", "f3" => "a", "f4" => nil, "f5" => 7,
      "f6" => "Beverages"}],
   shop: [%{"f1" => 29, "f2" => "Parnell Library", "f3" => 174.780063,
      "f4" => -36.863307}]},

其中f1 thorugh f4是产品字段,f5和f6是产品的类别字段。

0 个答案:

没有答案