2017-01-25 3 views
0

Beispieldaten aus meinem Tisch test_table:Return Zeilen, die maximal eine Spalte in Postgresql sind

date   symbol  value  created_time 
2010-01-09  symbol1  101  3847474847 
2010-01-10  symbol1  102  3847474847 
2010-01-10  symbol1  102.5  3847475500 
2010-01-10  symbol2  204  3847474847 
2010-01-11  symbol1  109  3847474847 
2010-01-12  symbol1  105  3847474847 
2010-01-12  symbol2  206  3847474847 

die Tabelle oben gegeben, Ich versuche, den optimalen Index zu finden auf dem Tisch (Datum, Symbol zu setzen,

date   symbol  value  created_time 
2010-01-09  symbol1  101  3847474847 
2010-01-10  symbol1  102.5  3847475500 
2010-01-10  symbol2  204  3847474847 
2010-01-11  symbol1  109  3847474847 
2010-01-12  symbol1  105  3847474847 
2010-01-12  symbol2  206  3847474847 

ich bin für jede Gruppe von denen drei mit der maximalen created_time für Datum, Symbol, Wert Datenspalte: Wert und created_time sollten eindeutig sein) und die Abfrage zu gehen zusammen zurückzukehren, um die folgende Kombination Spalte (im Wesentlichen Zeile 1, 3, 4, 5, 6, 7 in dem Beispiel abo zurückgekehrt sein).

Zur Zeit habe ich diesen Index versucht ...

CREATE UNIQUE INDEX "test_table_date_symbol_value_created_time" 
    ON "test_table" USING btree (date, symbol, value, created_time) 

Und diese Abfrage verwenden. Nicht sicher, ob es der effektivste Weg ist, es scheint immer noch ziemlich langsam.

select * 
    from(
    select date, 
      symbol, 
      value, 
      created_time, 
      max(created_time) over (partition by date, symbol) as max_created_time 
    from "test_table" 
) t 
where symbol in ('symbol1', 'symbol2') and created_time = max_created_time 
+0

So ist die gewünschte * neuesten * Zeile für jeden einzigartigen Datum, Symbol und Wertekombination ? – Bohemian

+0

Ja genau, tut mir leid, ich bin ziemlich unerfahren mit SQL, also habe versucht, viel zu lesen und eine fundierte Vermutung zu nehmen, bevor Sie fragen. –

+0

Sorry ich wollte die neueste Zeile für jedes Datum, Symbol Kombination sagen. –

Antwort

1

Postgres window functions unterstützt, die diese Situation anzupassen:

select date, symbol, value, created_time 
from (select *, 
    rank() over (partition by date, symbol order by created_time desc) as rownum 
    from test_table) x 
where rownum = 1 

Für jede Kombination von date, symbol Diese Abfrage gibt die value und created_time aus der Reihe mit dem höchsten (dh letzten) created_time davon date und symbol.

ich diesen Index vorschlagen würde:

CREATE UNIQUE INDEX test_table_idx 
    ON test_table (date, symbol, created_time, value) 

Es ist ein Abdeckung Index (hat alle Werte, die Sie für die Abfrage benötigen, wodurch die Notwendigkeit der tatsächlichen Tabelle zuzugreifen, und die Sie bereits hatte), aber Beachten Sie, dass created_time kommt vorvalue, so dass Daten bereits in seiner Partition Reihenfolge ist, und value ist das unwichtigste Attribut, weil es nicht in irgendeiner Bestimmung der Reihe, um zurückzukehren.

+0

Interessant, dass Sie für die Abfrage, wie könnte ich dies ändern, um nur das neueste Datum, Symbol eindeutige Kombination geben (so nur der letzte Wert wäre gegeben). Ich entschuldige mich, dass ich Ihren Kommentar oben falsch beantwortet habe. –

+0

@Trevor Ich habe 'Wert' von der Partition entfernt. – Bohemian

+0

Danke für die Erklärungen, sie machen sehr viel Sinn und scheinen zumindest bei meinen Tests bisher schneller zu sein als meine bisherigen Versuche.Obwohl ich created_time vor dem Wert verschoben habe, scheint es langsamer zu sein, aber ich weiß nicht so viel über Indizes, vielleicht ist es auf längere Sicht schneller mit weiteren Tests (ich habe jetzt ungefähr 2400 Symbole und ungefähr 11 Millionen Zeilen). –

0

Alternative:


SELECT * FROM test_table tt 
WHERE NOT EXISTS (
    SELECT * FROM test_table nx 
    WHERE nx."date" = tt."date" 
    AND nx.symbol = tt.symbol 
    AND nx.created_time > tt.created_time 
    ); 
Verwandte Themen