admin

在 Postgres 中为每个用户选择每第 N 行

sql

我正在使用这个 SQL 语句:

SELECT "dateId", "userId", "Salary" 
FROM (
   SELECT *, 
          (row_number() OVER (ORDER BY "userId", "dateId"))%2 AS rn 
   FROM user_table
 ) sa 
 WHERE sa.rn=1 
   AND "userId" = 789 
   AND "Salary" > 0;

但是每次表获得新行时,查询的结果都不同。
我错过了什么吗?


阅读 150

收藏
2021-07-01

共1个答案

admin

假设这("dateId", "userId")是唯一的并且新行总是有一个更大的(稍后)dateId

一些评论后:

认为你需要的是:

SELECT "dateId", "userId", "Salary"
FROM (
   SELECT "dateId", "userId", "Salary"
         ,(row_number() OVER (PARTITION BY "userId"   -- either this
                              ORDER BY "dateId")) % 2 AS rn
   FROM   user_table
   WHERE  "userId" = 789                              -- ... or that
   ) sub
WHERE  sub.rn = 1
AND    "Salary" > 0;

请注意PARTITION BY. 通过这种方式,您可以dateId为每个跳过每一秒userId,并且到目前为止,附加的(稍后的)行不会更改选择。

此外,只要您为单个 userId( WHERE "userId" = 789)选择行,将谓词拉入子查询,即可达到相同的效果(单个用户的稳定选择)。你不需要两者。

WHERE子查询中的条款仅适用于单个用户,PARTITION BY在一个查询适用于任何数量的用户。

2021-07-01