2016-12-21 6 views
0

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)サブクエリ((PasswordResetにおけるPR、から:pr.user_id()==^u.id()は、選択: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) 

はそれを実装する方法ですが、または私は何かが足りないのですか?エクト2.1.0のよう

+0

https://hexdocs.pm/ecto/Ecto.Query.html#subquery/1サブクエリは現在」と言います'from'と' join'フィールドでのみサポートされています。 "これはサブクエリではこれが不可能なようです。 – Dogbert

+0

@Dogbertこれについてのあなたの提案は何か、私はクエリの型情報を提供する必要があります。私は 'fragment/1'を使ってこの作品を作れますか? – Leviathlon

+1

'' p.inserted_at>フラグメントについてはどうですか? "(SELECT max(pr.inserted_at)FROM password_resets pr WHERE pr.user_id = u.id)") '? – Dogbert

答えて

2

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)") 
関連する問題