2017-05-30 5 views
0

Ich bin in der Lage, die folgende PSQL-Abfrage (am Ende) zu verwenden, um die dense_rank einer einzelnen Zeile in meiner Tabelle zu erhalten, möchte ich jedoch angezeigt werden können dies als:PSQL dose_rank eines Artikels aus verschiedenen Gesamtpositionen

dense_rank OUT OF total distinct ranks

da zum Beispiel dense_rank ermöglicht ‚Beziehungen‘, so zu sprechen, wenn ich 100 Zeilen haben und die gewählte Zeile 14. (und es gibt nur 59 verschiedene Reihen) gewählt, ich möchte sagen:

Ranked 14th out of 59

Gibt es eine Möglichkeit, meine Abfrage zu ändern, um dies zu erreichen, oder muss ich mehrere Abfragen verwenden?

Hier ist meine Frage:

SELECT ranked.* 
FROM 
    (SELECT id, 
      postable_id, 
      spread_count, 
      bury_count, 
      read_count, 
      (spread_count*3) + (bury_count*-2) + (read_count*-1) AS score, 
      dense_rank() OVER (
          ORDER BY (spread_count*3) + (bury_count*-2) + (read_count*-1) DESC) AS RANK 
    FROM posts) AS ranked 
WHERE id = ? 

Antwort

1

Sie können dies versuchen.

SELECT t.* 
FROM (SELECT ranked.*, 
     RNK||' out of '||MAX(RNK) OVER() as rnk_pos 
     FROM 
     (SELECT id, 
      postable_id, 
      spread_count, 
      bury_count, 
      read_count, 
      (spread_count*3) + (bury_count*-2) + (read_count*-1) AS score, 
      dense_rank() OVER (
          ORDER BY (spread_count*3) + (bury_count*-2) + (read_count*-1) DESC) AS RNK 
     FROM posts) AS ranked 
    ) t 
WHERE id=? 
+0

Dies scheint zu funktionieren, @vkp, danke! Kannst du diese schwarze Magie erklären, wenn du Zeit hast? Sehr geschätzt. – lightyrs

+1

@lightyrs .. die einzige zusätzliche Sache, die ich hinzugefügt habe, ist 'MAX (RNK) OVER()', die den maximalen Rang erhält (d. H. 59 in diesem Beispiel). 'RNK' ist das, was Sie bereits berechnet haben. Verketten sie Sie bekommt, was benötigt wird. –

0

Im Grunde wollen Sie diese:

SELECT p.* 
FROM (SELECT p.* 
      (spread_count*3) + (bury_count*-2) + (read_count*-1) AS score, 
      dense_rank() OVER (ORDER BY (spread_count*3) + (bury_count*-2) + (read_count*-1) DESC) AS RANK, 
      count(distinct (spread_count*3) + (bury_count*-2) + (read_count*-1)) over() as outof 
     FROM posts p 
    ) p 
WHERE id = ?; 

Ach, das funktioniert nicht, weil Postgres nicht COUNT(DISTINCT) als Fensterfunktion unterstützen. Sie können es mit anderen Fensterfunktionen implementieren: \

SELECT p.* 
FROM (SELECT p.*, 
      dense_rank() over (order by score desc) AS RANK, 
      sum((seqnum = 1)::int) as outof 
     FROM (SELECT p.*, 
        (spread_count*3) + (bury_count*-2) + (read_count*-1) AS score, 
        row_number() over (partition by (spread_count*3) + (bury_count*-2) + (read_count*-1) AS score order by spread_scount) as seqnum 
      FROM posts p 
      ) p 
    ) p 
WHERE id = ?; 
Verwandte Themen