2017-09-26 1 views
-1

i ont un message de table avec les colonnes suivantespostgres autre requête COUNT et ROW_NUMBER()

group_id BIGINT, 
user_id BIGINT, 
message_date timestamp 

pour le droit user_id je voudrais pouvoir compter les lignes au total avec ce user_id, les groupes distincts avec que user_id, et compte tenu d'un leaderboard faite par le comte de user_id, la position trop

j'ai essayé cette requête

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 

mais je ne suis pas le résultat que je voudrais avoir. Où ai-je tort?

+0

Veuillez fournir des données de l'échantillon et le résultat attendu. –

Répondre

1

La puissance des «données d'échantillon» et du «résultat attendu» est qu'elle permet aux autres de répondre efficacement. Ce qui suit est une estimation complète, mais peut-être vous invite à préparer un "Minimal, Complete, and Verifiable Example" (MCVE)

Les detials ci-dessous peut être consulté à SQL Fiddle

PostgreSQL 9.6 Configuration du schéma:

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') 
; 

Query 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 | 
+0

merci votre réponse est parfaite. Cela résout vraiment mon problème mais vous manquez une partie de ma requête: le WHERE id_utilisateur =% s je dois obtenir l'ensemble pour un user_id spécifique. j'ai essayé de l'ajouter dans votre version à la fin faire 'WHERE d.user_id =% s' mais alors la colonne' rnk' est toujours 1 avec chaque identifiant – 91DarioDev

+0

peut-être que je devrais faire votre requête comme une sous-requête et j'ajoute le où à la requête parent? – 91DarioDev

+0

Au fur et à mesure que vous y réfléchissez, réfléchissez ensuite à ce que vous devez faire pour répondre à une question où la cible finale n'est pas connue ... Vous devrez exécuter toute cette requête avant de pouvoir obtenir le bon classement d'une personne utilisateur. Maintenant vous devez considérer l'efficacité de cela et combien de fois vous voulez vraiment faire ceci etc. mais ces considérations sont bien en dehors de la portée de cette question. –

0

En regardant simplement la requête intérieure, je vois cela dans la sélection:

SELECT user_id, COUNT(group_id), ... 

Mais dans le GROUPE PAR:

GROUP BY user_id, group_id 

Mettez les ensemble, et vous ne serez jamais un COUNT() résultat de tout autre que 1, parce que chaque group_id a son propre groupe. Cela fonctionne pour la même chose pour la colonne total_m.

+0

Alors, comment pourrais-je obtenir le résultat attendu? Pas moyen de le faire dans une requête? – 91DarioDev