简体   繁体   中英

Ecto update query using value from a subquery

I want to update a field based on the value of an aggregate subquery on the same table. In plain SQL (in my case, PostgreSQL) it could look like this:

UPDATE
    things
SET
    sort_order = (
        SELECT
            min(sort_order) - 1
        FROM
            things
        WHERE
            related_field_id = 123)
WHERE
    things.id = 2

So basically I want to set the sort_order of a record in things to 1 less than the current lowest sort_order of a subset of records in the same table.

I've tried somthing like

lowest_order =
  from(t in Thing,
    where: t.related_field_id == 123,
    select: fragment("MIN(?) - 1", t.sort_order)
  )

from(t in Thing,
  update: [set: [sort_order: subquery(lowest_order)]]
)

But ecto doesn't accept this as a valid query expression. Is there a way to achieve the above? Perhaps this approach is sub-optimal so I'm happy to hear alternatives.

I know this is an old question, so you might not need this answer anymore, but hopefully this helps someone.

lowest_order =
  from(t in Thing,
    where: t.related_field_id == 123,
    select: %{lowest_order: fragment("MIN(?) - 1", t.sort_order)}
  )

from(t in Thing,
  join: sub in subquery(lowest_order),
  where: t.id == 2,
  update: [set: [sort_order: sub.lowest_order]]
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM