2017-09-06 1 views
0

Ich möchte Zellen in jeder Zeile nehmen und sie in eine Reihe von Namen machen ... Meine Methode befasst sich bereits mit Gehäuse.kombinieren verschiedene Zeilenwerte in eine Zeichenfolge - sql

Zum Beispiel die Tabelle;

'john' |  | 'smith' | 'smith'  
'john' | 'paul' |   | 'smith' 
'john' | 'john' | 'john' |  

kehrt:

'john smith' 
'john paul smith' 
'john' 

Dies müßte postgreSQL 8.2.15 von Postgres laufen, so dass ich keinen Gebrauch von potentiell nützlichen Funktionen wie CONCAT machen, und die Daten werden in einem Greenplum db.

Alternativ könnte eine Methode zum direkten Löschen von doppelten Tokens in einer Liste von Strings das größere Ziel erreichen. Zum Beispiel:

'john smith john smith' 
'john john smith' 
'smith john smith' 

kehrt

'john smith' 
'john smith' 
'smith john' 

Die Reihenfolge der Token ist nicht wichtig, solange alle die einzigartigen Werte zurückgegeben werden, nur einmal. Normalisieren

Dank

+0

Dies scheint eine schlechte DB-Design und ich denke, Sie brauchen eine Anwendungsebene. –

Antwort

2

Ihre Tabellenstruktur, wählen Sie eindeutige Namen Werte aus dieser Tabelle, erstellen Sie eine Funktion zu aggregieren Strings (siehe beispielsweise How to concatenate strings of a string field in a PostgreSQL 'group by' query?), und diese Funktion anwenden. Abgesehen von der Aggregatfunktionserstellung könnte dies alles in einer einzigen Anweisung oder Ansicht erfolgen.

+0

Danke - nicht sicher, wie ich diese Frage überhaupt verpasst habe; Ich verbrachte einige Stunden damit, ähnliche Probleme zu finden. – MREES

0

Ich würde dies tun, indem die Daten unpivoting und dann reaggregation:

select id, string_agg(distinct col) 
from (select id, col1 from t union all 
     select id, col2 from t union all 
     select id, col3 from t union all 
     select id, col4 from t 
    ) t 
where col is not null 
group by id; 

Dies setzt voraus, dass jede Zeile eine eindeutige ID hat.

Sie können auch ein riesiger case verwenden:

select concat_ws(',', 
       col1, 
       (case when col2 <> col1 then col2 end), 
       (case when col3 <> col2 and col3 <> col1 then col3 end), 
       (case when col4 <> col3 and col4 <> col2 and col4 <> col1 then col4 end) 
       ) as newcol 
from t; 

In alten Versionen von Postgres können Sie Phrase dies als:

select trim(leading ',' from 
      (coalesce(',' || col1, '') || 
      (case when col2 <> col1 then ',' || col2 else '' end) || 
      (case when col3 <> col2 and col3 <> col1 then ',' || col3 else '' end), 
      (case when col4 <> col3 and col4 <> col2 and col4 <> col1 then ',' || col4 else '' end) 
      ) 
      ) as newcol 
from t; 
+0

Die Funktion string_agg() ist in PG 8.2 nicht verfügbar. –

+0

@rd_nielsen. . . Es gibt eine zweite Antwort. –

+0

Ja; Die Funktion concat() war auch nicht in PG 8.2. Ich denke, der Ansatz mit string_agg() ist am besten, aber eine benutzerdefinierte Aggregatfunktion muss hinzugefügt werden (was in PG wirklich einfach ist). –

0

Ich habe für dich mit einer Lösung zu kommen! :)

Die folgende Abfrage gibt die vier Spalten zurück (die ich col_1,2,3und 4 nannte) und entfernt die Duplikate, indem Sie die test_table mit sich selbst verbinden.Hier

ist der Code:

SELECT t1.col_1, t2.col_2, t3.col_3, t4.col_4 

FROM (
    SELECT id, col_1 
     FROM test_table 
) AS t1 

LEFT JOIN (
    SELECT id, col_2 
     FROM test_table 
) as t2 

ON (t2.id = t1.id and t2.col_2 <> t1.col_1) 


LEFT JOIN (
    SELECT id, col_3 
     FROM test_table 
) as t3 

ON (t3.id = t1.id and t3.col_3 <> t1.col_1 and t3.col_3 <> t2.col_2) 



LEFT JOIN (
    SELECT id, col_4 
     FROM test_table 
) as t4 

ON (t4.id = t1.id and t4.col_4 <> t1.col_1 and t4.col_4 <> t2.col_2 and t4.col_4 <> t3.col_3); 

Wenn Sie die letzte Zeichenfolge erhalten möchten, können Sie einfach ersetzen die „SELECT“ Zeile mit dieser:

SELECT trim(both ' ' FROM (COALESCE(t1.col_1, '') || ' ' || COALESCE(t2.col_2, '') || ' ' || COALESCE(t3.col_3, '') || ' ' || COALESCE(t4.col_4, ''))) 

sollte dies mit Ihrer Version arbeiten von postgres entsprechend mit der Dokumentation:

[für die Trimm- und Verkettungsfunktionen]

https://www.postgresql.org/docs/8.2/static/functions-string.html

// ****************************************** *********

[für die coalesce Funktion]

https://www.postgresql.org/docs/8.2/static/functions-conditional.html

Bitte lassen Sie mich wissen, wenn ich Hilfe waren :)

PS Ihre Frage klingt wie ein schlechtes Datenbankdesign: Ich würde diese Spalten in eine Tabelle verschieben, in der Sie diese Operation ausführen könnten, indem Sie eine Gruppe mit oder ähnlichem verwenden. Außerdem würde ich die String-Verkettung in einem separaten Skript durchführen. Aber das ist meine Art zu tun :)

Verwandte Themen