2017-10-04 3 views
1

Meine Prognose Tabelle speichert die aktuelle Woche, und dann für 26 Wochen prognostizierten Beträge aus:POSTGRES transponiert Wochenspalten in Zeilen?

CREATE TABLE forecast_listings (
    product integer NOT NULL 
, current_week_date date 
, weekplus0 integer NOT NULL DEFAULT 0 
, weekplus1 integer NOT NULL DEFAULT 0 
, weekplus2 integer NOT NULL DEFAULT 0 
, weekplus3 integer NOT NULL DEFAULT 0 
, weekplus4 integer NOT NULL DEFAULT 0 
-- etc 
, weekplus24 integer NOT NULL DEFAULT 0 
, weekplus25 integer NOT NULL DEFAULT 0 
); 

Zum Beispiel ein einzelnes Element prognostiziert, wähle ich eine einzelne Zeile mit der neuesten current_week_date und dann bei relativ Wochen aussehen.

SELECT 
unnest(
    array[ 
    to_char(week_current_date, 'YYYY-MM-DD'), 
    to_char(week_current_date + interval '1 weeks', 'YYYY-MM-DD'), 
    to_char(week_current_date + interval '2 weeks', 'YYYY-MM-DD'), 
    to_char(week_current_date + interval '3 weeks', 'YYYY-MM-DD'), 
    to_char(week_current_date + interval '4 weeks', 'YYYY-MM-DD') 
    -- ...all the way to 25 
    ] 
) AS "Week", 
unnest(
    array[ 
    weekplus0, 
    weekplus1, 
    weekplus2, 
    weekplus3, 
    weekplus4 
    -- ...all the way to 25 
    ] 
) AS "Count" 
FROM (
    SELECT * FROM forecast_listings 
    WHERE product_id = 1 
    ORDER BY week_current_date DESC 
    LIMIT 1 
) as row 

Ich mag würde dies mit Postgres zu tun, im Wesentlichen eine Reihe und zur Umsetzung der einzelnen Wochen Zahl in eine Reihe mit einer Datumsspalte holen und zählen Spalte:

week, count 
2017-10-01,100 
2017-10-08,200 
2017-10-15,150 
etc. 
+0

Bitte klären. 'asin',' valid_as_of' (du meinst 'current_week_date'?) und' weekcurrent' ('weekplus0'?) sind nicht in deiner Tabellendefinition. Und was ist mit dem * "Monat" * im Titel? Ich half mit und ersetzte die Liste der Spalten durch eine 'CREATE TABLE'-Anweisung, mit der wir arbeiten können. Und einige Syntax-Fixes. Geben Sie einige Beispielwerte und Ihre Version von Postgres an. Ich bin mir ziemlich sicher, dass es eine elegante Lösung gibt ... –

+0

@ErwinBrandstetter Ja, ich habe die Frage auf eine einfache Frage reduziert, was eine bessere Möglichkeit ist, diese wöchentlichen Daten aus Spaltenwerten in getrennte Zeilen zu transponieren. –

+0

Also hast du deine Antwort? –

Antwort

0
SELECT to_char(f.week_current_date + interval '1 week' * w, 'YYYY-MM-DD') 
    , arr[w+1] 
FROM (
    SELECT week_current_date 
     , ARRAY[weekplus0, weekplus1, weekplus2, weekplus3] AS arr -- add all 26 
    FROM forecast_listings 
    WHERE product_id = 1 
    ORDER BY week_current_date DESC NULLS LAST -- ? 
    LIMIT 1 
    ) f 
CROSS JOIN LATERAL generate_series(0, 25) w; 

Das Hauptmerkmal ist a CROSS JOIN LATERAL bis generate_series() um die gewünschten Zeilen zu generieren. Verwenden Sie eine ARRAY constructor wie Sie bereits in der Unterabfrage hatten. Der generierte Index w wird verwendet, um dem Basisdatum Wochen hinzuzufügen und auf entsprechende Array-Elemente zuzugreifen. Achten Sie auf einen lauernden "Off-by-1" -Fehler, da Postgres-Array-Indizes standardmäßig 1-basiert sind. Verwandte:

Da week_current_date NULL-Werte zu ermöglichen scheint, können Sie ORDER BY week_current_date DESCverwenden NULLS LAST, um Zeilen mit NULL-Werten zu sortieren, die sonst oben wären. Siehe:

Verwandte Themen