SQL - Werte einer Spalte aneinanderhängen

BrainPain

Well-Known Member
Hallo Leute,

ich habe einen String, aufgrund der vorgegebenen Feldgröße auf mehrere Zeilen verteilt. Ist es möglich diesen String mit nur einem Select vollständig zurück zu erhalten? Ich finde es etwas lästig dies im Programm selbst zu erledigen.
Es muss nicht unbedingt ANSI-SQL sein, MSSQL-Syntax würde mir in diesem Fall reichen.

Ich weis das man Felder beim selektieren mit '+' aneinander hängen kann aber mein eigentliches Problem ist das ich zu diesem Zeitpunkt nicht weis wieviele Zeilen ich habe, sonst könnte ich ja eine entsprechende Anzahl von subselects verwenden. (Aber eigentlich interessiert mich diese Anzahl nicht sondern nur der String)

Gibt es vielleicht noch einen anderen Lösungsansatz?

Viele Grüße
 
Hast du es mal mit "concat" versucht? Ich weiß nicht ob das bei MSSQL auch "concat" heißt, aber als Stichwort "Verkettung" hilft dir vielleicht was?
 
Das klingt nach einem kaputten Dankenbankmodell.

Woher weißt Du, wie viele Zeilen zu einem String zusammengehören? Gibt es eine eindeutige ID?

Ich würde das über eine Stored Procedure machen, die die einzelnen Selects durchführt, den String in einer Variablen concateniert und diese dann zurückliefern. Ich kenne aber MySQL nicht, sondern nur Postgres und MSSQL, keine Ahnung, ob es da Prozeduren gibt.
 
Hast du es mal mit "concat" versucht? Ich weiß nicht ob das bei MSSQL auch "concat" heißt, aber als Stichwort "Verkettung" hilft dir vielleicht was?
concat gibt es auch in MSSQL jedoch hilf das mir nicht da ich dafür wissen müsste wieviele zeilen es sind und dann eine entsprechende anzahl von verschachtelten concats durchführen müsste, da man mit concat nur 2 werte aneinander hängen kann.

Das klingt nach einem kaputten Dankenbankmodell.
Halte ich für eine SEHR gewagte Feststellung.

Woher weißt Du, wie viele Zeilen zu einem String zusammengehören? Gibt es eine eindeutige ID?
Ja die gibt es. Diese ist jedoch nur für die Reihenfolge relevant. In dieser Tabelle werden für die Applikation benutzerdefinierte Werte nach dem Key/Value-Prinzip abgelegt. Also ist in diesem Falle eher der Key interessant. Das hat jedoch rein garnichts mit dem eigentlichen Problem (Aneinanderhängen von Werten aus verschiedenen Zeilen) zu tun.

Ich würde das über eine Stored Procedure machen, die die einzelnen Selects durchführt, den String in einer Variablen concateniert und diese dann zurückliefern. Ich kenne aber MySQL nicht, sondern nur Postgres und MSSQL, keine Ahnung, ob es da Prozeduren gibt.

Stored Procedures sind keine Option, da:
1. keine Rechte vorhanden sind diese anzulegen und
2. jeder Kunde der diese Datenbank einsetzt (und das sind viele) dann diese Stored Procedure benötigen würde nur um meine Applikation verwenden zu können.

Von MySQL war nie die Rede. Aber da es ja gerade um MSSQL geht kannst du mir vielleicht weiterhelfen. Ganz so trivial scheint es jedenfalls nicht zu sein denn Google wusste nicht weiter. Mittlerweile glaube ich auch nicht dass es geht.

Viele Grüße
 
Hhm, mit dem MySQL muss ich mich wohl verlesen haben.

Mach doch bitte mal ein konkretes Beispiel (Tabellenstruktur, Inhalt). Muss nicht viel sein, aber nur, damit ich mir das mal bildlich vorstellen kann. Mir ist das Problem nicht ganz klar.
 
Hhm, mit dem MySQL muss ich mich wohl verlesen haben.

Mach doch bitte mal ein konkretes Beispiel (Tabellenstruktur, Inhalt). Muss nicht viel sein, aber nur, damit ich mir das mal bildlich vorstellen kann. Mir ist das Problem nicht ganz klar.

Keine Ahnung welche Rolle das spielt aber meinetwegen:

(vereinfachte) Tabelle:
ID | Key | Value (max 99 Zeichen)
------------------------------------------------------
1 | wert_1 | 'Das ist '
2 | wert_2 | 'ein ganz '
3 | wert_3 | 'tolles Beispiel'

Wie schon geschrieben, ist diese Tabelle stark vereinfacht, da im Original der Key aus 3 Komponenten besteht und zudem noch Informationen bezüglich der Zugriffsrechte für jeden Datensatz gespeichert werden usw. Aber dies ist hier nicht relevant.

Viele Grüße
 
(vereinfachte) Tabelle:
ID | Key | Value (max 99 Zeichen)
------------------------------------------------------
1 | wert_1 | 'Das ist '
2 | wert_2 | 'ein ganz '
3 | wert_3 | 'tolles Beispiel'

Die Verwendung eines Cursors könnte helfen:

Code:
DECLARE @result as varchar(255)
DECLARE @zeile as varchar(100)
SET @result = ''

DECLARE result_cursor CURSOR FOR
    SELECT value FROM mytable ORDER BY id

OPEN result_cursor

FETCH NEXT FROM result_cursor INTO @zeile
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @result = @result+@zeile
    
    FETCH NEXT FROM result_cursor INTO @zeile
END
CLOSE result_cursor
DEALLOCATE result_cursor

SELECT @result

Das sollte funktionieren. Der Datentyp von @result muss entsprechend groß gewählt werden, die Select-Anweisung für den Cursor muss noch sinnvoll eingeschränkt werden (auch die gewünschten Keys zum Beispiel).

Viel Erfolg!
 
Die Verwendung eines Cursors könnte helfen:

Code:
DECLARE @result as varchar(255)
DECLARE @zeile as varchar(100)
SET @result = ''

DECLARE result_cursor CURSOR FOR
    SELECT value FROM mytable ORDER BY id

OPEN result_cursor

FETCH NEXT FROM result_cursor INTO @zeile
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @result = @result+@zeile
    
    FETCH NEXT FROM result_cursor INTO @zeile
END
CLOSE result_cursor
DEALLOCATE result_cursor

SELECT @result

Das sollte funktionieren. Der Datentyp von @result muss entsprechend groß gewählt werden, die Select-Anweisung für den Cursor muss noch sinnvoll eingeschränkt werden (auch die gewünschten Keys zum Beispiel).

Viel Erfolg!

Vielen Dank für deine Mühe, aber wie ich bereits am Anfang gesagt habe benötige ich ein Select-Statement. Scheinbar geht es nicht...also muss ich es dabei belassen das ich die Werte im Programm zusammenführe. Trotzdem Danke.
 
Code:
  DECLARE @titles AS varchar(255)
  SET @titles = ''

  SELECT @titles = RTRIM(LTRIM(@titles + ISNULL(Spalte,''))) + ', '
  FROM Tabelle 

  RETURN
    CASE
      WHEN LEN(@titles) > 0 THEN LEFT(@titles, LEN(@titles) - 1)
      ELSE @titles
    END

Das ganze kannste natürlich auch noch in eine Funktion packen und entsprechend Parametrisieren um es dann in einer normalen "SELECT"-Anweisung zu nutzen.
 
Code:
  DECLARE @titles AS varchar(255)
  SET @titles = ''

  SELECT @titles = RTRIM(LTRIM(@titles + ISNULL(Spalte,''))) + ', '
  FROM Tabelle 

  RETURN
    CASE
      WHEN LEN(@titles) > 0 THEN LEFT(@titles, LEN(@titles) - 1)
      ELSE @titles
    END

Das ganze kannste natürlich auch noch in eine Funktion packen und entsprechend Parametrisieren um es dann in einer normalen "SELECT"-Anweisung zu nutzen.

Wie bereits gesagt ist dies keine Option.
 
Die obigen Zeilen sind zumindest ohne Prozedur im Query Analyzer ausführbar.

Ich bin mir jedoch nicht ganz sicher, ob man den Codeschnipsel in ein PreparedStatement packen kann, theoretisch sollte das gehen.
Falls aber nicht, gibts in SQL keine andere Lösung (die ich kenne), daher ist das Thema in der Applikation besser aufgehoben.
 
Ich bin mir jedoch nicht ganz sicher, ob man den Codeschnipsel in ein PreparedStatement packen kann, theoretisch sollte das gehen.
Das wage ich zu bezweifeln, da meines Wissens nach lediglich DELETE-, INSERT-, UPDATE- und SELECT-Statements zulässig sind.


@codephreaker:
Stored Procedures sind keine Option, da:
1. keine Rechte vorhanden sind diese anzulegen und
2. jeder Kunde der diese Datenbank einsetzt (und das sind viele) dann diese Stored Procedure benötigen würde nur um meine Applikation verwenden zu können.
 
der neugierhalber würd ich gern wissen warum du das über mehrere Zeilen verteilst ?
aus MySQL Sicht würd ich jetzt ein "Text" oder wenns wesentlich länger sein soll "Longtext" Feld und hätte mir dann nich soviel stress mit dem zusammenführen gemacht..

ansonsten ne simple idee.. eindeutige id
also laut deiner minitabelle wär das ungefähr so:
Code:
ID | Key | stringID | Value (max 99 Zeichen)
------------------------------------------------------
1 | wert_1 | 111 | 'Das ist '
2 | wert_2 | 111 |  'ein ganz '
3 | wert_3 | 111 |  'tolles Beispiel'

müsstest halt das im Proggi zusammenführen (grad keine idee/lust n SQL zusammenzubasteln)

und die daten einfach mit "Select * from tabelle where stringid = '111'" oder so .. dann einfach im proggi das Array durchlaufen bis du alle werte drin has und die schön an einander gereiht fertig..

das wär jetzt mein Ansatz auf die Schnelle
 
der neugierhalber würd ich gern wissen warum du das über mehrere Zeilen verteilst ?
aus MySQL Sicht würd ich jetzt ein "Text" oder wenns wesentlich länger sein soll "Longtext" Feld und hätte mir dann nich soviel stress mit dem zusammenführen gemacht..
Ja klar, wenn ich Einfluss auf das DB-Design hätte wäre das auch der Fall. Nun wie ich bereits geschrieben habe ist es aber so das mir vorgegeben ist wo ich diese "benutzerdefinierten" Werte in dieser vorgegebenen Datenbank abzulegen habe. Und die betreffende Spalte hat nunmal eine vorgegebene Breite von 99 Zeichen. (zur Info: Diese Datenbank bildet die Basis eines CRM-Systems und sollte daher wegen den bereits genannten Gründen nicht modifiziert werden)

ansonsten ne simple idee.. eindeutige id
also laut deiner minitabelle wär das ungefähr so:
Code:
ID | Key | stringID | Value (max 99 Zeichen)
------------------------------------------------------
1 | wert_1 | 111 | 'Das ist '
2 | wert_2 | 111 |  'ein ganz '
3 | wert_3 | 111 |  'tolles Beispiel'

müsstest halt das im Proggi zusammenführen (grad keine idee/lust n SQL zusammenzubasteln)
Schade, denn um genau DIESE Idee dreht sich der gesamte Thread. Außerdem ist die Spalte stringID in deinem Beispiel überflüssig, da bereits ein eindeutiger Schlüssel vorhanden ist welcher, wie ich bereits geschrieben hatte, aus 3 Spalten(ohne Datensatz-ID) besteht.

und die daten einfach mit "Select * from tabelle where stringid = '111'" oder so .. dann einfach im proggi das Array durchlaufen bis du alle werte drin has und die schön an einander gereiht fertig..
Klar, das ist meine bisherige Vorgehensweise. Diesen Thread habe ich jedoch gestartet weil ich gerne die Zusammenführung des urpsrünglichen Strings auf die Datenbank verlagern möchte, da diese das mit Sicherheit schneller hinbekommt.

Trotzdem vielen Dank für deine Mühe
 
Keine wirkliche Hilfe für dich, aber ein paar Anmerkungen Fragen für dich:

concat gibt es auch in MSSQL jedoch hilf das mir nicht da ich dafür wissen müsste wieviele zeilen es sind und dann eine entsprechende anzahl von verschachtelten concats durchführen müsste, da man mit concat nur 2 werte aneinander hängen kann.
Nur zwecks der Neugierde:
Ist das ANSI-SQL "CONCAT" nicht das MSSQL "+"? Mit "+" kann man aber mehr wie 2 Werte verketten. (Zumindest laut der Doku vom SQL-Server 2005, in der ich CONCAT dafür überhaupt nicht finde.)

Das wage ich zu bezweifeln, da meines Wissens nach lediglich DELETE-, INSERT-, UPDATE- und SELECT-Statements zulässig sind.
Das solltest du ja wohl als erstes klären, ob und wieso nur dieses Statements zugelassen sind?

An einem DECLARE oder SET ist ja ansonsten nichts besonderes.

Gegeben hast du uns diese Beispieltabelle:
Code:
ID | Key    | Value (max 99 Zeichen)
------------------------------------------------------
1  | wert_1 | 'Das ist '
2  | wert_2 | 'ein ganz '
3  | wert_3 | 'tolles Beispiel'
Analog zu den Beispielen oben, sollte es (wenn DECLARE und SET geht) eigentlich auch schon so funktionieren:
Code:
declare @result varchar(8000);
set @result = '';
select @result = @result + t.Value from Tabelle t;
select @result;
Halt noch ein WHERE für dein "Key" und ein passendes "ORDER BY" mit dranbasteln.
 
Keine wirkliche Hilfe für dich...
Damit hast du wohl recht.

Habe ich nicht schon oft genug geschrieben dass ich lediglich EIN select-Statement haben möchte? Warum wird mir dann immer wieder vorgeschlagen das Datenbank-Design zu verändern, Stored Procedures anzulegen oder mehrere DB-Statements (mit Cursor usw.) mit meinem Programm abzuschicken welches dann so tun soll als wäre es nur ein Statement (so ein Quatsch)?
Habe ich mich vielleicht falsch ausgedrückt?

Im übrigen sehe ich den Thread als erledigt an, da weder mit Google noch hier eine Lösung zu finden war.

Viele Grüße

P.S.
Das angesprochene Programm von mir ist nicht in Java geschrieben.
 
Habe ich mich vielleicht falsch ausgedrückt?
Nein, aber nicht jede Aufgabe lässt sich in /einem/ SELECT erledigen. Eben dafür haben die SQL-Macher z.B. lokale Variablen "erfunden". Die muss man in einem ersten Query/Statement dann halt erst einmal einrichten.
 
Zurück
Oben