我正在使用这个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;
但每次表格获得新行时,查询结果都不同 我错过了什么吗?
答案 0 :(得分:5)
假设("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
适用于一个查询中的任意数量的用户。
是吗?是吗?
他们应该给我“侦探”徽章。
<子>严重。子> 子> 子>
答案 1 :(得分:0)
不,这似乎没问题。 您有新行,这些行会在排序后更改旧行以显示在不同位置。
答案 2 :(得分:0)
如果有人插入一个userId低于789的新行,则订单会发生变化。 例如,如果您有:
userId rn
1 1
4 0
5 1
6 0
并且你插入一行userId = 2,rn将改变:
userId rn
1 1
2 0
4 1
5 0
6 1
为了选择每个第N行,您需要一个带有序列或时间戳的列。