【问题标题】:Providing subquery in query parameters在查询参数中提供子查询
【发布时间】:2020-04-28 21:41:54
【问题描述】:

我需要用 Ecto 实现以下查询,但是它不能编译,说子查询语句不是有效的表达式。

query = from p in Passphrase,
        left_join: pi in PassphraseInvalidation, on: p.id == pi.target_passphrase_id,
        join: u in User, on: p.user_id == u.id,
        where: p.passkey == ^passkey and
               is_nil(pi.inserted_at) and
               p.inserted_at > ago(5, "month") and
               p.inserted_at > subquery(from pr in PasswordReset,
                                        where: pr.user_id == u.id,
                                        select: max(pr.inserted_at)),
        select: {u, p}

user = Repo.one!(query)

(Ecto.Query.CompileError) subquery(from(pr in PasswordReset, where: pr.user_id() == ^u.id(), select: max(pr.inserted_at()))) 无效查询表达式。

等效的 PgSQL 查询类似于:

SELECT u.*, p.*
FROM passphrases p
LEFT OUTER JOIN passphrase_invalidations pi ON p.id = pi.target_passphrase_id
INNER JOIN users u ON p.user_id = u.id
WHERE p.passkey = '/* some passkey */' AND
      pi.inserted_at IS NULL AND
      u.id = 2 AND
      p.inserted_at > (SELECT max(pr.inserted_at)
                       FROM password_resets pr
                       WHERE pr.user_id = u.id)

有没有办法实现它,还是我错过了什么?

【问题讨论】:

  • hexdocs.pm/ecto/Ecto.Query.html#subquery/1 表示“子查询目前仅在 fromjoin 字段中受支持。”所以现在看来​​这对于子查询是不可能的。
  • @Dogbert 您对此有何建议,我需要在查询中提供类型信息。我可以使用“片段/1”来完成这项工作吗?
  • p.inserted_at > fragment("(SELECT max(pr.inserted_at) FROM password_resets pr WHERE pr.user_id = u.id)") 怎么样?
  • @Dogbert 你能提供这个作为答案吗?

标签: postgresql elixir ecto


【解决方案1】:

从 Ecto 2.1.0 开始,根据https://hexdocs.pm/ecto/Ecto.Query.html#subquery/1,子查询不能在where 中使用:

目前仅在fromjoin 字段中支持子查询。

您现在可以使用fragment 并将整个子查询放入其中:

p.inserted_at > fragment("(SELECT max(pr.inserted_at) FROM password_resets pr WHERE pr.user_id = u.id)")

【讨论】:

    【解决方案2】:

    where 刚刚可用(Ecto 3.4.3)

    https://hexdocs.pm/ecto/Ecto.Query.html#subquery/2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多