2017-04-26 6 views
0

Ich baue eine Tabelle in Redshift als Basis für eine Bowling Chart.Redshift SQL: Inter-Zeile Berechnungen basierend auf einer anderen Spalte

habe ich meine Daten in diesem Format:

data:

 
month | product_id | kpi_type | values 
april |  1  | current | 330 
april |  1  | target | 300 
april |  2  | current | 340 
april |  2  | target | 300 
march |  2  | current | 270 
march |  2  | target | 300 

Ich möchte ein wo diff = current-target einzufügen.

Suche auf diese zu bekommen:

 
month | product_id | kpi_type | values 
april |  1  | current | 330 
april |  1  | target | 300 
april |  1  | diff  | 30 
april |  2  | current | 340 
april |  2  | target | 300 
april |  2  | diff  | 40 
march |  2  | current | 270 
march |  2  | target | 300 
march |  2  | diff  | -30 

Ich weiß, wie es zu erhalten, indem die diff in CTEs Berechnung und unioning es dann zu der ursprünglichen Tabelle. Jedoch möchte ich dies über viele verschiedene values und mit komplexeren Varianzformeln tun, also suche ich nach einer effizienteren Lösung.

Hier, wo ich:

 

    select 
     a.month, 
     a.product_id, 
     a.values as current, 
     b.target, 
     a.values - b.target as diff 
    from data a 
    left join 
     (
      select 
      month, 
      product_id, 
      values as target 
      from data 
      where kpi_type = 'target' 
     ) b 
    on md5(a.month || a.product_id) = md5(b.month || b.product_id) 
    where kpi_type = 'current' 
    group by 1,2,3 

Von dort konnte ich Gewerkschaft es zurück zu data und das gewünschte Ergebnis erhalten, aber es ist nicht effizient zu sein scheinen.

Close to this question on SQL Server.

+0

Wenn Sie nach einer "effizienten" Lösung suchen, sollten Sie eine Zeile pro Monat + Produktkombination speichern und den aktuellen und das Ziel als Spalten speichern (anstatt als separate Zeilen). Dies wird Ihre Berichterstattung viel einfacher machen. Sie könnten Ihre vorhandene Tabelle in eine andere Tabelle dieses Formats umwandeln (ETL) und die neue Tabelle für Abfragen verwenden. –

+0

Einverstanden, leider muss ich die 'kpi_types' als Zeilen für Visualisierungszwecke haben, wenn ich in mein bi-Tool ziehe - ich suche das gleiche Format wie der Link, auf den in der Frage verwiesen wird, und mein bi-Werkzeug ist spaltenbasiert. – tristangk

Antwort

1

Angenommen es gibt nur einen Wert pro Monat, product_id für kpi_types current und target, können Sie aggregieren, um die Diff-Zeile zu erhalten und union all verwenden, um sie mit dem ursprünglichen Ergebnis zu kombinieren.

select month,product_id,kpi_type,values from data 
union all 
select month,product_id,'diff' as kpi_type, 
coalesce(max(case when kpi_type='current' then values end),0) - 
coalesce(max(case when kpi_type='target' then values end),0) as values 
from data 
group by month,product_id 
0

Ich konnte die Kommentarfunktion nicht verwenden. Also werde ich es hier schreiben. Ich denke, es gibt keinen anderen Weg, als mithilfe von union Daten in Rotverschiebung zu transponieren. Sie können also die Fensterfunktion für die Subtraktion anstelle der linken Join-Abfrage verwenden, um diff zu erhalten.

sum(values) 
    OVER (
     PARTITION BY month, product_id) AS diff 

Zuerst Sie könnten in einem Sub-Abfrage so etwas tun:

SELECT 
     CASE WHEN type = 'target' 
     THEN values * -1 
     ELSE values END AS values 
    FROM data 

Dann können Sie Vereinigung es.

Verwandte Themen