Postgres查询不同的COUNT和ROW_NUMBER()

时间:2017-09-26 21:20:35

标签: sql postgresql group-by

我有一个包含以下列的表消息

group_id BIGINT, 
user_id BIGINT, 
message_date timestamp

对于正确的user_id,我希望能够计算具有该user_id的总行数,具有该user_id的不同组,并考虑由user_id计数生成的排行榜,该位置也是。

我试过了这个查询

SELECT main.total_m, main.group_number, main.pos 
FROM (
    SELECT user_id, COUNT(group_id) AS group_number, COUNT(user_id) AS total_m,  
        ROW_NUMBER() OVER (
            PARTITION BY COUNT(user_id)
            ORDER BY COUNT(user_id) DESC
            ) AS pos 
    FROM messages
    WHERE message_date > date_trunc('week', now())
    GROUP BY user_id, group_id
) AS main 
WHERE user_id = %s

但我没有得到我想要的结果。我哪里错了?

2 个答案:

答案 0 :(得分:1)

“样本数据”和“预期结果”的力量使其他人能够有效地回答。以下是一个完整的猜测,但它可能会提示您准备一个“Minimal, Complete, and Verifiable Example”(MCVE)

可以在SQL Fiddle

访问以下详细信息

PostgreSQL 9.6架构设置

CREATE TABLE Messages
    (USER_ID int, GROUP_ID int, MESSAGE_DATE timestamp)
;

INSERT INTO Messages
    (USER_ID, GROUP_ID, MESSAGE_DATE)
VALUES
    (1, 7, '2017-09-01 10:00:00'),
    (1, 6, '2017-09-02 10:00:00'),
    (1, 5, '2017-09-03 10:00:00'),
    (1, 4, '2017-09-04 10:00:00'),
    (1, 7, '2017-09-05 10:00:00'),
    (2, 6, '2017-09-01 10:00:00'),
    (2, 5, '2017-09-02 10:00:00'),
    (2, 7, '2017-09-03 10:00:00'),
    (2, 6, '2017-09-04 10:00:00'),
    (2, 4, '2017-09-05 10:00:00'),
    (2, 8, '2017-09-11 10:00:00')
;

查询1

select
      user_id
    , num_grps
    , num_msgs
    , dense_rank() over(order by num_grps DESC, num_msgs DESC, max_date DESC, user_id) rnk
from (
    select
          user_id
        , count(distinct group_id) num_grps
        , count(*)                 num_msgs
        , max(message_date)        max_date
    from messages
    group by
          user_id
    ) d

<强> Results

| user_id | num_grps | num_msgs | rnk |
|---------|----------|----------|-----|
|       2 |        5 |        6 |   1 |
|       1 |        4 |        5 |   2 |

答案 1 :(得分:0)

仅查看内部查询,我在select:

中看到了这一点
SELECT user_id, COUNT(group_id), ...

但这在GROUP BY:

GROUP BY user_id, group_id

将这些放在一起,除了COUNT()之外,你永远不会有1个结果,因为每个group_id都拥有自己的群组。它适用于total_m列。