2017-06-09 2 views
0

Ich habe eine Abfrage, die die meisten wiederkehrenden Wert von my_table wählt. Die Abfrage ist unter:Wie zu korrigieren falsch am häufigsten wiederkehrenden Wert in PostgreSQL

SELECT 
gid, 
    max_height 
    FROM 
    (
    SELECT gid, max_height, 
    ROW_NUMBER() OVER (PARTITION BY gid ORDER BY freq DESC) AS rn 
    FROM (
      SELECT gid, max_height, COUNT(id) AS freq 
      FROM my_table 
      GROUP BY 1, 2 
    order by 1,2 
    ) hgt_freq 
    ) ranked_hgt_req 
WHERE rn = 1 

während my_table enthält drei Spalten wie:

gid id max_height 
3 1 19.3 
3 2 19.3 
3 3 20.3 
3 4 20.3 
3 5 19.3 
3 6 19.3 
3 7 21.4 
3 8 21.4 
3 9 21.4 
3 10 21.4 
3 11 21.4 
3 12 21.4 
22 1 23.1 
22 2 23.1 
22 3 23.1 
22 4 23.1 
22 5 23.1 
22 6 23.1 
22 7 22.1 
22 8 22.1 
22 9 22.1 
22 10 22.1 
22 11 22.1 
22 12 22.1 
29 1 24 
29 2 24 
29 3 24 
29 4 18.9 
29 5 18.9 
29 6 18.9 
29 7 NULL 
29 8 NULL 
29 9 27.1 
29 10 27.1 
29 11 6.5 
29 12 6.5 

Das Problem bei dieser Abfrage ist, dass es die meisten sich wiederholenden Wert in absteigender Reihenfolge zurückgibt, die für den falschen Wert zu geben Fall des GID = 22. der Ausgang der Abfrage ist:

gid max_height 
3  21.4 
22  22.1 
29  24.0 

Für den Fall von GID = 22, gibt es zwei am meisten sich wiederholenden Werte, dh, 23,1 und 22,1. Daher sollte die Abfrage 23.1 zurückgeben. Kann mir jemand zeigen, wie ich dieses Problem beheben kann, oder gibt es einen besseren Ansatz dafür? Der Prozess muss für große Datensätze (GIDs) automatisiert werden.

Antwort

2

Verwenden distinct on:

select distinct on(gid) gid, max_height 
from (
    select gid, max_height, count(id) as freq 
    from my_table 
    group by 1, 2 
    ) s 
order by gid, freq desc 

gid | max_height 
-----+------------ 
    3 |  21.4 
    22 |  23.1 
    29 |   24 
(3 rows) 

Von the documentation:

DISTINCT ON (expression [...]) SELECT hält nur die erste Zeile eines jeden Satzes von Zeilen, in denen die angegebenen Ausdrücke zu bewerten, gleich. Die DISTINCT ON-Ausdrücke werden mit den gleichen Regeln wie für ORDER BY interpretiert (siehe oben). Beachten Sie, dass die "erste Zeile" jedes Satzes nicht vorhersehbar ist, es sei denn, ORDER BY wird verwendet, um sicherzustellen, dass die gewünschte Zeile zuerst angezeigt wird.


Es gibt zwei häufigsten Werte für gid=29. In Fällen wie diesen Sie in welcher Reihenfolge können wählen, sollten sie durch das Hinzufügen einer weiteren Bedingung in order by präsentiert:

select distinct on(gid) gid, max_height 
from (
    select gid, max_height, count(id) as freq 
    from my_table 
    group by 1, 2 
    ) s 
order by gid, freq desc, max_height desc; 

gid | max_height 
-----+------------ 
    3 |  21.4 
    22 |  23.1 
    29 |   24 
(3 rows)  

select distinct on(gid) gid, max_height 
from (
    select gid, max_height, count(id) as freq 
    from my_table 
    group by 1, 2 
    ) s 
order by gid, freq desc, max_height; 

gid | max_height 
-----+------------ 
    3 |  21.4 
    22 |  22.1 
    29 |  18.9 
(3 rows)  
+0

Ich frage mich, wie es 24 für gid zurück = 29 in Ihrem Fall. Für mich kam es 18.9 zurück. Ich habe diese Max_Heights 21.4, 23.1, 18.9 für gid 3, 22, 29. Ich bin verwirrt. Irgendeine Idee warum ist es so? –

+0

Dies liegt daran, dass die Reihenfolge von 'max_height' nicht definiert ist, siehe die modifizierte Antwort. – klin

+0

Ja, es hat funktioniert! Vielen Dank. –

Verwandte Themen