[英]How to spread/distribute a number in Postgres SQL
I have a table as follows:我有一个表如下:
id rank user
1 1 1
2 1 1
3 1 2
4 2 1
5 2 1
I would like to spread the rank
value for a given user between 1 (or 0) and a max value to leave space between values.我想将给定用户的
rank
值分布在 1(或 0)和最大值之间,以在值之间留出空间。 For example, I would like to spread the rank
for user 1
, with max value of 100 (in this case), the result should be:例如,我想传播用户
1
的rank
,最大值为 100(在这种情况下),结果应该是:
id rank user
1 20 1
2 40 1
3 1 2
4 60 1
5 80 1
I thought to calculate an increment = maxValue / count(items) + 1
and then do many UPDATE
queries using the increment
for each new one, but that seems extremely inefficient.我想计算一个
increment = maxValue / count(items) + 1
,然后使用每个新的increment
执行许多UPDATE
查询,但这似乎效率极低。 Is there a way to do it better, maybe with one big UPDATE
query, something like:有没有办法做得更好,也许使用一个大的
UPDATE
查询,例如:
UPDATE MyTable
SET rank = increment * ??? (?current position? in SELECT * FROM MyTable WHERE user = 1 ORDER BY rank)
WHERE user = 1
You could achieve this result by using a CTE
to generate a row number ( rn
) for each entry for a user (in order of rank
with id
to order duplicates) and also a count ( cnt
) of the number of rows for that user, and then set the rank
for that user to be:您可以通过使用
CTE
为用户的每个条目生成行号 ( rn
)(按照id
的rank
顺序对重复项进行排序)以及该用户的行数的计数 ( cnt
) 来实现此结果,然后将该用户的rank
设置为:
rn * 100 / (cnt + 1)
As a query:作为查询:
WITH CTE AS (
SELECT id, user,
ROW_NUMBER() OVER (PARTITION BY user ORDER BY rank, id) AS rn,
COUNT(*) OVER (PARTITION BY user) AS cnt
FROM MyTable
WHERE "user" = 1
)
UPDATE MyTable
SET rank = CTE.rn * 100 / (CTE.cnt + 1)
FROM CTE
WHERE MyTable.id = CTE.id
Resultant table:结果表:
id rank user
1 20 1
2 40 1
3 1 2
4 60 1
5 80 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.