如何根据计数进行更新 - SQL (postgres)

Rob*_*nes 2 sql postgresql

我有一张桌子,我们称之为“条目”,看起来像这样(简化):

id [pk]
user_id [fk]
created [date]
processed [boolean, default false]
Run Code Online (Sandbox Code Playgroud)

并且我想创建一个 UPDATE 查询,它将在所有条目上将处理的标志设置为 true,除了每个用户的最新 3 个(就创建的列而言是最新的)。因此,对于以下条目:

1,456,2009-06-01,false
2,456,2009-05-01,false
3,456,2009-04-01,false
4,456,2009-03-01,false
Run Code Online (Sandbox Code Playgroud)

只有条目 4 会将它的处理标志更改为 true。

有谁知道我怎么能做到这一点?

Ste*_*ass 5

我不知道 postgres,但这是标准 SQL,可能对你有用。

update entries set
  processed = true
where (
  select count(*)
  from entries as E
  where E.user_id = entries.user_id
  and E.created > entries.created
) >= 3
Run Code Online (Sandbox Code Playgroud)

换句话说,只要在以后的日期有三个或更多相同 user_id 的条目,就将已处理的列更新为 true。我假设 [created] 列对于给定的 user_id 是唯一的。如果没有,您将需要一个额外的标准来确定您的意思是“最新”。

在 SQL Server 中,您可以这样做,这更容易遵循并且可能会更有效地执行:

with T(id, user_id, created, processed, rk) as (
  select
    id, user_id, created, processed,
    row_number() over (
      partition by user_id
      order by created desc, id
    )
  from entries
)
  update T set
    processed = true
  where rk > 3;
Run Code Online (Sandbox Code Playgroud)

更新 CTE 是一项非标准功能,并非所有数据库系统都支持 row_number。