2013-06-18 23 views
7

Piszę aplikację, którą napisałem, aby uruchomić na Apache przy użyciu PHP i bazy danych MySQL. Jedno z zapytań wykorzystywało funkcje MySQL z Concat_WS i Group_Concat do łączenia kilku różnych kolumn w jeden ciąg, a następnie łączenia wszystkich elementów pogrupowanych według klauzuli Group_By.Spełnienie Mysql Group_Concat w SQL Server

Jako przykład:

ID Name Candy 
1  John M&Ms 
1  John KitKat 

Zapytanie:

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

Rezultat:

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

Teraz staram się osiągnąć ten sam wynik w SQL Server 2008 przy użyciu PHP 5.4+.

Co próbowałem:

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

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

Oczekiwany wynik będzie:

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

Wreszcie, to staje się jeszcze trudniejsze, gdy dodam więcej kolumn do mieszanki. Chcę scalić wyniki (jak pokazano powyżej), gdzie identyfikator jest taki sam. Działa to bardzo dobrze z group_concat, ponieważ automatycznie łączy wiersze, które zostały zgrupowane razem.

+1

@bluefeet Widziałem już to pytanie, ale staram się unikać używania XML. Naprawdę chciałem zachować ten sam format, który użyłem w poprzedniej wersji aplikacji. –

+0

Istnieją sposoby na uzyskanie danych w odpowiednim formacie, ale w serwerze SQL nie ma łatwego sposobu łączenia danych z wielu wierszy w jeden. – Taryn

+1

@bluefeet Jak mogę zmienić to pytanie, aby uzyskać odpowiedź i nie zamknąć? Poczyniłem dzisiaj masę lektury na ten temat i nadal nie mam go w sobie (oczywiście jak teraz jestem tutaj) –

Odpowiedz

7

Można to zrobić w dwuetapowym procesie.

Najpierw można użyć funkcji Common Table Expression, aby wykonać pierwsze połączenie name i candy. Pierwsza część wykorzystuje zapytanie:

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

Zobacz Demo. To daje wynik:

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

Po początkowym konkatenacji jest zrobione, wtedy można użyć FOR XML PATH i STUFF aby uzyskać ostateczny wynik:

;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; 

Zobacz SQL Fiddle with Demo. Daje to wynik:

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

Naprawdę doceniam tę odpowiedź. Spróbuję użyć go z moim faktycznym zestawem danych, który jest oczywiście znacznie bardziej skomplikowany niż to, co napisałem. Zrobię co w mojej mocy, aby działało zgodnie z oczekiwaniami, ale jeśli nie mogę, opublikuję tutaj kilka. Dzięki jeszcze raz. –

+0

To działało idealnie. Nie jestem pewien, czego mi brakowało, żeby być szczerym. Myślę, że to, że zapytanie zostało podzielone na dwie części, było tym, co poradziło. Doceniam to, że nie śpieszysz się, aby to zamknąć, chociaż odpowiedzi są dostępne, ponieważ nie miałem szczęścia z żadnym z nich. –

+0

@Whathaveyoutried Cieszę się, że to działa. – Taryn