跨行而不是列的Postgres percent_rank

问题描述

数据:

我有一个postgres表,其中的每一行都包含一个question_id,并计算用户按下按钮时的值。

 +----------+-----------+------+-----+----------+
| Question | Very Good | Good | Bad | Very Bad |
+----------+-----------+------+-----+----------+
| 1        | 23        | 12   | 23  | 67       |
+----------+-----------+------+-----+----------+
| 2        | 56        | 90   | 23  | 18       |
+----------+-----------+------+-----+----------+

要求:

我希望能够将每一行值转换为总行数的百分比。

+----------+-----------+-------+-------+----------+
| Question | Very Good | Good  | Bad   | Very Bad |
+----------+-----------+-------+-------+----------+
| 1        | 18.4      | 9.6   | 18.4  | 53.8     |
+----------+-----------+-------+-------+----------+
| 2        | 29.94     | 48.12 | 12.29 | 9.6      |
+----------+-----------+-------+-------+----------+

尝试: 我发现percent_rank()会向我显示基于列的百分比,我想知道是否有类似的功能可以按行工作?

    SELECT 
question_id,PERCENT_RANK() OVER (
        ORDER BY Very_good
    ),PERCENT_RANK() OVER (
        ORDER BY Good
    )
PERCENT_RANK() OVER (
        ORDER BY Bad
    )
PERCENT_RANK() OVER (
        ORDER BY Very Bad
    )
FROM Question_Feedback

解决方法

恐怕唯一可行的方法是手动执行此操作:

SELECT 
question_id,Very_good::double precision / (Very_good + Good + Bad + Very_bad),Good::double precision      / (Very_good + Good + Bad + Very_bad),Bad::double precision       / (Very_good + Good + Bad + Very_bad),Very_bad::double precision  / (Very_good + Good + Bad + Very_bad)
FROM Question_feedback

好消息是它将比PERCENT_RANK更快,因为它只需要考虑该行,这要便宜得多。

,

Working Solution

WITH QUESTION_FEEDBACK
     AS (SELECT 1 AS QUESTION,23 VERYGOOD,12 GOOD,23 BAD,67 VERYBAD
         UNION ALL
         SELECT 2 AS QUESTION,56 VERYGOOD,90 GOOD,18 VERYBAD
           )
SELECT QUESTION,VERYGOOD,GOOD,BAD,VERYBAD,(CAST(VERYGOOD  AS DECIMAL) / SUM (VERYGOOD + GOOD + BAD + VERYBAD) OVER (PARTITION BY QUESTION))*100 VERYGOODPER,(CAST(GOOD AS DECIMAL)   / SUM (VERYGOOD + GOOD + BAD + VERYBAD) OVER (PARTITION BY QUESTION))*100 GOODPER,(CAST(BAD AS DECIMAL)  / SUM (VERYGOOD + GOOD + BAD + VERYBAD) OVER (PARTITION BY QUESTION) )*100 BADPER,(CAST(VERYBAD AS DECIMAL)  / SUM (VERYGOOD + GOOD + BAD + VERYBAD) OVER (PARTITION BY QUESTION))*100 VERYBADPER      
  FROM QUESTION_FEEDBACK