2012-04-10 2 views
3

Ich habe ein Ergebnis aus einer Abfrage wie die unten, die nicht eine feste Anzahl von Spalten enthältPostgreSQL Zeile String

ID COL1 COL2 COL3 COL4 
------------------------------------- 
1 VAL11 VAL12 VAL13 VAL14 
2 VAL21 VAL22 VAL23 VAL24 

Jetzt möchte ich das Ergebnis, so etwas sein.

RESULT 
----------------------------------------------------- 
ID:1, COL1:VAL11, COL2:VAL12, COL3:VAL13, COL4:VAL14 
ID:2, COL1:VAL21, COL2:VAL22, COL3:VAL23, COL4:VAL24 

Bitte helfen Sie.

Antwort

3

Die schnelle und schmutzige Art und Weise, aber ohne die Spaltennamen und einschließlich NULL-Werte:

SELECT tbl::text 
FROM tbl; 

Der langsame & sichere Weg:

SELECT array_to_string(ARRAY[ 
      'ID:' || id 
     ,'COL1:' || col1 
     ,'COL2:' || col2 
     ], ', ') AS result 
FROM tbl; 

Wenn eine Spalte einen hält NULL Wert, wird es im Ergebnis fehlen. Ich verkette nicht nur, weil NULL Werte die ganze Reihe annullieren würden.
array_to_string() stellt sicher, dass Kommas nur dort eingefügt werden, wo sie benötigt werden.


PostgreSQL 9.1 eingeführt, um die neue Funktion concat_ws() (ähnlich wie die in MySQL), mit dem wir weiter vereinfachen:

SELECT concat_ws(', ' 
      'ID:' || id 
     ,'COL1:' || col1 
     ,'COL2:' || col2 
     ) AS result 
FROM tbl; 
+2

Wäre die zweite Möglichkeit nicht viel einfacher, wenn Sie die Werte einfach verketten, anstatt zunächst ein Array zu erstellen und dieses Array dann in eine Zeichenfolge zurück zu konvertieren? –

+1

@a_horse_with_no_name: Wie würden Sie dann mit 'NULL' Werten umgehen? Sie würden für jede Spalte eine 'CASE'-Anweisung benötigen und es wäre schwer, die Kommas passend zu machen. Kenne ich schon. Es ist viel einfacher so. Ohne 'NULL' Werte hätten Sie jedoch recht. –

+0

Guter Punkt. Ich habe nicht an die NULL-Werte gedacht. –

1
SELECT 
      'ID:' ||coalesce(id::text, '<null>') 
    ||', '||'COL1:'||coalesce(col1::text, '<null>') 
    ||', '||'COL2:'||coalesce(col2::text, '<null>') 
FROM tbl; 

Sie diese SQL verwenden kann, die ersten zu erzeugen eine für Sie (falls es viele Säulen gibt):

SELECT E'SELECT \n'||string_agg(trim(stmt), E' \n')||E'\n FROM tbl;' 
    FROM (SELECT 
    CASE WHEN a.attnum > 1 THEN $$||', '||$$ ELSE '' END || 
    $$'$$||upper(a.attname)||$$:'||coalesce($$||quote_ident(a.attname)|| 
    $$::text, '<null>')$$ AS stmt 
    FROM pg_attribute a, pg_class t 
WHERE t.relkind='r' AND t.relname = 'tbl' AND a.attrelid = t.oid 
    AND NOT a.attisdropped AND a.attnum > 0) AS s; 
+0

Wenn Sie einen Platzhalter für Spalten mit NULLs ersetzen, wird es einfacher. Der schwierige Teil besteht darin, 'NULL'-Spalten zu trimmen. Angenommen, die erste Spalte ist NULL, oder die erste und die zweite ... Seit Seite 9.1 können Sie mit 'concat_ws()' weiter vereinfachen. –