【问题标题】:How do I translate a Where clause subquery into an Ecto join?如何将 Where 子句子查询转换为 Ecto 连接?
【发布时间】:2019-09-11 23:39:32
【问题描述】:

我目前有两个具有 hasMany 关系的表:

customers [hasMany] items

items 内有一些belongsTo 关系:

providers [belongsTo] items
statuses [belongsTo] items
types [belongsTo] items

我的目标是有一个 Ecto 查询,它返回一个 customers 列表,其中至少有一个 items 记录,其中 status_id 为 2 以及该 customers 记录具有的任何其他 items

我还需要预加载itemsprovidersstatusestypes

我在 SQL 中复制了如下:

SELECT
distinct on (c0.id)
  c0."id", 
  c0."inserted_at", 
  c0."updated_at", 
  c1."id", 
  c1."inserted_at", 
  c1."updated_at"
FROM "customers" AS c0
  INNER JOIN "items" AS c1 ON c1."customer_id" = c0."id"
WHERE EXISTS (
  SELECT * 
  FROM "items" c2
  WHERE c2."customer_id" = c0."id"
    AND c2.status_id = 2);

这与我当前的 Ecto 查询有点逆向工程:

Repo.all( 
from(p in Customers,
inner_join: r in assoc(p, :items),
where: r.status_id == 2,
preload: [
  items: r, items: :provider, items: :type, items: :status
  ],
  )
)

此 Ecto 查询为我提供了具有 status_id 为 2 的项目的客户,但它仅返回符合条件的项目记录。如果其中一条记录的 status_id 为 2,我希望拥有与该客户关联的所有项目。

我尝试通过使用子查询作为连接来实现这一点,如下所示:

Repo.all( 
from(p in Customers,
inner_join: r in assoc(p, :items),
join: i in subquery(from(i in MyApp.Items, where: i.status_id == 2 )), on: p.id == i.id,
preload: [
  items: r, items: :provider, items: :type, items: :status
  ]
  )
)

但是,这不会返回任何结果。非常感谢 Ecto 专家的任何见解。

【问题讨论】:

    标签: elixir ecto phoenix


    【解决方案1】:

    编辑:看起来你应该在你的join: ... 中用on: p.id == i.customer_id, 替换on: p.id == i.id,

    本文档Ecto subquery

    看起来我们可以通过连接过滤 status_id 为 2 的所有客户+项目,然后我们得到所有这些客户的列表,并预加载了他们的所有项目。

    还要注意用于获取嵌套关联的更简单的预加载结构。

    我在我的一个类似结构的数据库上测试成功,希望对你有用

    import Ecto.Query
    
    from(c in Customers,
      join: i in subquery(
        from(i in Items,
          where: i.status_id == 2
        )
      ),
      on: i.customer_id == c.id,
      preload: [items: [:provider, :type, :status]]
    ) |> Repo.all
    

    【讨论】:

    • 我唯一的遗憾是我只有一张赞成票可以给。这会产生完美的回报。我可以在我的原始帖子中看到我哪里出错了。我也很欣赏有关嵌套关联语法的重要提示
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-23
    • 2021-08-08
    相关资源
    最近更新 更多