2013-06-18 5 views
7

Ich portiere eine Anwendung, die ich ursprünglich geschrieben habe, um auf Apache mit PHP und einer MySQL-Datenbank zu laufen. Eine der Abfragen verwendete die MySQL-Funktionen Concat_WS und Group_Concat, um zuerst ein paar verschiedene Spalten in eine Zeichenfolge zu verketten und dann alle Elemente, die durch die Group_By-Klausel gruppiert wurden, zu verketten.Ich erfülle MYSQL's Group_Concat in SQL Server

Als Beispiel:

ID Name Candy 
1  John M&Ms 
1  John KitKat 

Die Abfrage:

Select Group_Concat(Concat_WS('-',Name, Candy) Separator '00--00') as UserCandy 
From ExampleTable 
Group By ID 

Das Ergebnis:

UserCandy 
John-M&Ms00--00John-KitKat 

Nun, ich versuche, das gleiche Ergebnis in SQL Server 2008 zu erreichen mit PHP 5.4+.

Was ich versucht habe:

SELECT Stuff(name + ';' + candy, 1, 0, '-----') AS UserCandy 
FROM test 

Das Problem can be seen in the fiddle that I have setup.

Das erwartete Ergebnis wäre:

-----John;MMs-----John;KitKat 

Schließlich dies wird noch schwieriger, wenn ich mehr Spalten in den Mix. Ich möchte die Ergebnisse zusammenführen (wie oben gezeigt), wo die ID die gleiche ist. Dies funktioniert sehr gut mit group_concat, weil es automatisch Zeilen zusammenfassen wird, die zusammen gruppiert wurden.

+1

@bluefeet Ich habe diese Frage bereits gesehen, aber ich versuche, die Verwendung von XML zu vermeiden. Ich wollte wirklich das gleiche Format beibehalten, das ich in der vorherigen Version der App verwendet hatte. –

+0

Es gibt Möglichkeiten, die Daten in dem gewünschten Format zu erhalten, aber in SQL Server gibt es keine einfache Möglichkeit, Daten aus mehreren Zeilen in einem einzigen zu verketten. – Taryn

+1

@bluefeet Also, wie könnte ich diese Frage so ändern, dass sie beantwortet und nicht geschlossen wird? Ich habe heute eine Menge über das Thema gelesen und ich habe es immer noch nicht selbst verstanden (offensichtlich, wie ich jetzt hier bin) –

Antwort

7

Dies kann in einem zweistufigen Prozess erfolgen.

Zuerst können Sie einen gemeinsamen Tabellenausdruck verwenden, um die erste Verkettung von name und candy durchzuführen. Der erste Teil verwendet eine Abfrage:

;with cte as 
(
    select id, name+';'+ candy UserCandy 
    from table_test 
) 
select * 
from cte 

Siehe Demo. Daraus ergibt sich ein Ergebnis:

| ID | USERCANDY | 
-------------------- 
| 1 | John;MMs | 
| 1 | John;KitKat | 

Sobald die erste Verkettung erfolgt, dann können Sie FOR XML PATH und STUFF verwenden um das Endergebnis zu erhalten:

;with cte as 
(
    select id, name+';'+ candy UserCandy 
    from table_test 
) 
select distinct c.id, 
    STUFF(
     (SELECT '-----' + c2.UserCandy 
      FROM cte c2 
      where c.id = c2.id 
      FOR XML PATH ('')) 
      , 1, 0, '') AS UserCandy 
from cte c; 

Siehe SQL Fiddle with Demo. Dies ergibt ein Ergebnis:

| ID |      USERCANDY | 
-------------------------------------- 
| 1 | -----John;MMs-----John;KitKat | 
+0

Ich schätze diese Antwort sehr. Ich werde versuchen, es mit meinem tatsächlichen Datensatz zu verwenden, der natürlich viel komplizierter ist als das, was ich gepostet habe. Ich werde mein Bestes tun, um es wie erwartet zur Arbeit zu bringen, aber wenn ich nicht kann, werde ich hier in ein paar posten. Danke noch einmal. –

+0

Das hat perfekt funktioniert. Ich bin mir nicht sicher, was ich vermisst habe, um ehrlich zu sein. Ich denke, dass die Tatsache, dass die Abfrage in zwei Teile aufgeteilt wurde, der Trick war. Ich weiß es zu schätzen, dass du nicht hastig bist, das zu schließen, obwohl die Antworten da draußen sind, da ich mit keinem von ihnen Glück hatte. –

+0

@Whathaveyoutried Ich bin froh, dass es funktioniert hat. – Taryn