2016-04-29 1 views
1

Nehmen wir an, es gibt eine Tabelle "Elemente", die drei Spalten hat: "ID", "POS" und "Neg", und das Ergebnis der Auswahl sollte durch das Ergebnis der Operation pos - neg bestellt werden.Postgres: Wie erhält man die Zeilennummer, wenn sie nach dem Operationsergebnis geordnet ist?

So wird die folgende funktionieren soll:

SELECT 
    id, 
    pos - neg AS diff 
FROM items 
ORDER BY diff DESC 

Jetzt muss ich Position einer bestimmten Zeile bekommen (in der Tabelle), um das Ergebnis der Bestellung von ‚diff‘. Ich habe es versucht:

WITH summary AS (
    SELECT 
     i.id, 
     i.pos - i.neg AS diff, 
     ROW_NUMBER() OVER(ORDER BY diff) AS position 
    FROM items i) 
SELECT s.* FROM summary s WHERE s.id = 351435254 

aber die Ausführung gibt Fehler zurück: Spalte "Diff" existiert nicht.

Also, ist es möglich, die Position zu bekommen, oder wäre es besser, Diffs in einer separaten Spalte zu halten?

+0

diff ist ein Alias ​​Versuch 'ROW_NUMBER() OVER (ORDER BY i .pos - i.neg) AS position' statt –

+0

@Richard, der funktioniert! Vielen Dank! – aspermag

Antwort

0

Versuchen:

WITH summary AS (
    SELECT 
     i.id, 
     i.pos - i.neg AS diff, 
     ROW_NUMBER() OVER(ORDER BY (i.pos - i.neg)) AS position 
    FROM items i) 
SELECT s.* FROM summary s WHERE s.id = 351435254 
+0

Das funktioniert, danke! Irgendwie habe ich nicht einmal daran gedacht, weil ich tatsächlich eine komplexere Berechnung als 'pos-neg' habe ... – aspermag

1

Um zu vermeiden, um die Berechnung zu wiederholen, sondern nur die ROW_NUMBER() auf der äußeren Abfrage zu bewegen ...

WITH summary AS (
    SELECT 
     i.id, 
     i.pos - i.neg AS diff  
    FROM 
     items i 
) 
SELECT 
    s.*, 
    ROW_NUMBER() OVER(ORDER BY s.diff) AS position 
FROM 
    summary s 
WHERE 
    s.id = 351435254 

Während der inneren Abfrage Verweise auf diff wird Anwendungsbereich beschränkt auf was existierte vor der SELECT, sonst können Sie Zirkelverweise erhalten.

Zum Zeitpunkt der äußeren Abfrage Ihr neues Feld diff vorhanden ist, und kann so als Parameter für andere Berechnungen, Funktionen geliefert werden, usw.

+0

Danke! Aber ich habe vergessen zu sagen, dass ich die Position einer Zeile innerhalb der gesamten Tabelle brauche, nicht die Auswahl ... – aspermag

+0

Gleicher Ansatz, haben drei Ebenen der verschachtelten Abfrage. Innerstes berechnet Diff, Nächstes Level berechnet Position, Nächstes Level wendet die Where-Klausel an. Das ist aber teuer, der ganze Tisch muss berechnet und sortiert werden ... – MatBailie

Verwandte Themen