代码之家  ›  专栏  ›  技术社区  ›  Carlo

postgresql中数字的分布

  •  1
  • Carlo  · 技术社区  · 6 年前

    我有一张桌子如下:

    id    rank    user
    1      1       1
    2      1       1
    3      1       2
    4      2       1
    5      2       1
    

    我想把这个摊开 rank 给定用户的值介于1(或0)和最大值之间,以便在值之间留出空间。例如,我想传播 等级 1 ,最大值为100(在本例中),结果应为:

    id    rank    user
    1      20      1
    2      40      1
    3      1       2
    4      60      1
    5      80      1
    

    increment = maxValue / count(items) + 1 然后做很多 UPDATE 使用 increment 但这似乎效率极低。有没有办法做得更好,也许用一个大的 更新 查询,类似于:

    UPDATE MyTable
    SET rank = increment * ??? (?current position? in SELECT * FROM MyTable WHERE user = 1 ORDER BY rank)
    WHERE user = 1
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Nick SamSmith1986    6 年前

    您可以通过使用 CTE 生成行号( rn )对于用户的每个条目(按 rank 具有 id 订购副本)以及计数( cnt ),然后设置 等级

    rn * 100 / (cnt + 1)
    

    作为查询:

    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
    

    结果表:

    id  rank    user
    1   20      1
    2   40      1
    3   1       2
    4   60      1
    5   80      1
    

    Demo on SQLFiddle