Tabela jest:
+----+------+
| Id | Name |
+----+------+
| 1 | aaa |
| 1 | bbb |
| 1 | ccc |
| 1 | ddd |
| 1 | eee |
+----+------+
Wymagana moc wyjściowa:
+----+---------------------+
| Id | abc |
+----+---------------------+
| 1 | aaa,bbb,ccc,ddd,eee |
+----+---------------------+
Pytanie:
SELECT ID,
abc = STUFF(
(SELECT ',' + name FROM temp1 FOR XML PATH ('')), 1, 1, ''
)
FROM temp1 GROUP BY id
To zapytanie działa poprawnie. Potrzebuję tylko wyjaśnienia, jak to działa, czy jest jakiś inny lub krótki sposób, aby to zrobić.
Jestem bardzo zdezorientowany, aby to zrozumieć.
sql
sql-server
database
Puneet Chawla
źródło
źródło
ID
jest unikalny w innej tabeli różnych podmiotów, a ta tabela przechowuje rzeczy, które do nich należą.Odpowiedzi:
Oto jak to działa:
1. Pobierz ciąg elementu XML za pomocą FOR XML
Dodanie ŚCIEŻKI XML na końcu zapytania umożliwia wyświetlenie wyników zapytania w postaci elementów XML z nazwą elementu zawartą w argumencie ŚCIEŻKA. Na przykład, jeśli mielibyśmy uruchomić następującą instrukcję:
Przekazując pusty ciąg (FOR XML PATH ('')), otrzymujemy zamiast tego:
2. Usuń przecinek wiodący za pomocą STUFF
Instrukcja STUFF dosłownie „upycha” jeden ciąg na inny, zastępując znaki w pierwszym ciągu, jednak używamy go po prostu do usunięcia pierwszego znaku z wynikowej listy wartości.
Parametry
STUFF
to:W rezultacie otrzymujemy:
3. Dołącz do id, aby uzyskać pełną listę
Następnie po prostu dołączamy do tego na liście identyfikatorów w tabeli tymczasowej, aby uzyskać listę identyfikatorów o nazwie:
I mamy nasz wynik:
Mam nadzieję że to pomoże!
źródło
LISTAGG
funkcję w Oracle 11gR2. Tęsknię za tą funkcjonalnością w dniach, w których muszę z niej korzystać. techonthenet.com/oracle/functions/listagg.phplist
działa od dziesięcioleci. Niestety zamiast tego SQLServer firmy Microsoft oparty na ASE Sybase, i nigdy nie przejmował się funkcją listy aż do zeszłego roku. Zgadzam się - to zadziwiające. A potem to robią, nazywają tostring_agg
. Myślałem, żelist
to całkiem oczywiste.W tym artykule omówiono różne sposoby konkatenacji ciągów SQL, w tym ulepszoną wersję kodu, który nie koduje XML skonkatenowanych wartości.
Aby zrozumieć, co się dzieje, zacznij od wewnętrznego zapytania:
Ponieważ określasz
FOR XML
, otrzymasz pojedynczy wiersz zawierający fragment XML reprezentujący wszystkie wiersze.Ponieważ nie określono aliasu kolumny dla pierwszej kolumny, każdy wiersz zostałby zawinięty w element XML o nazwie podanej w nawiasach po znaku
FOR XML PATH
. Na przykład, gdybyś miałFOR XML PATH ('X')
, dostaniesz dokument XML, który wyglądałby tak:Ponieważ jednak nie podałeś nazwy elementu, otrzymujesz listę wartości:
Po
.value('.', 'varchar(max)')
prostu pobiera wartość z wynikowego fragmentu XML, bez kodowania XML żadnych „znaków specjalnych”. Masz teraz ciąg, który wygląda następująco:Następnie
STUFF
funkcja usuwa wiodący przecinek, dając końcowy wynik, który wygląda następująco:Na pierwszy rzut oka wygląda dość myląco, ale zwykle działa całkiem dobrze w porównaniu do niektórych innych opcji.
źródło
TYPE
xml
nvarchar(max)
name
TYPE
i.value('.', 'varchar(max)')
, możesz w rezultacie uzyskać encje zakodowane w XML.Tryb PATH służy do generowania XML z zapytania SELECT
Dane wyjściowe to XML zorientowany na elementy, w którym każda wartość kolumny w wynikowym zestawie wierszy jest zawinięta w element wiersza. Ponieważ klauzula SELECT nie określa aliasów dla nazw kolumn, wygenerowane nazwy elementów potomnych są takie same jak odpowiadające im nazwy kolumn w klauzuli SELECT.
Do każdego wiersza w zestawie wierszy dodawany jest znacznik.
W kroku 2: Jeśli określisz ciąg o zerowej długości, element owijający nie zostanie utworzony.
W kroku 4 łączymy wartości.
W kroku 6 grupujemy datę według identyfikatora.
STUFF (ciąg_źródłowy, początek, długość, ciąg_dodany) Parametry lub argumenty ciąg_źródłowy Ciąg źródłowy do modyfikacji. start Pozycja w łańcuchu_źródłowym, aby usunąć znaki długości, a następnie wstawić łańcuch_odpowiedzi. długość Liczba znaków do usunięcia z łańcucha_źródłowego. add_string Sekwencja znaków do wstawienia do łańcucha_źródłowego w pozycji początkowej.
źródło
','
podana jako kolumna w połączeniu ze('')
ścieżką po xml powoduje konkatenacjęSELECT 'a' FROM some_table FOR XML PATH('')
będzie produkować:'aaaaaaa'
. Ale jeśli nazwa kolumny zostaną określone:SELECT 'a' AS Col FROM some_table FOR XML PATH('')
uzyskać wynik:<Col>a</Col><Col>a</Col><Col>a</Col>
Dostępna jest bardzo nowa funkcjonalność w bazie danych SQL Azure i SQL Server (począwszy od 2017 r.) Do obsługi tego dokładnie scenariusza. Wierzę, że posłuży to jako natywna oficjalna metoda tego, co próbujesz osiągnąć za pomocą metody XML / STUFF. Przykład:
STRING_AGG - https://msdn.microsoft.com/en-us/library/mt790580.aspx
EDYCJA: Kiedy pierwotnie to opublikowałem, wspomniałem o SQL Server 2016, ponieważ myślałem, że widziałem to w potencjalnej funkcji, która miała zostać uwzględniona. Albo zapamiętałem to niepoprawnie, albo coś się zmieniło, dziękuję za sugerowaną edycję naprawiającą wersję. Poza tym byłem pod wrażeniem i nie byłem w pełni świadomy wieloetapowego procesu recenzji, który właśnie przyciągnął mnie do ostatecznej opcji.
źródło
W
for xml path
, jeśli zdefiniujemy dowolną wartość,[ for xml path('ENVLOPE') ]
wówczas te tagi zostaną dodane do każdego wiersza:źródło
Tutaj w powyższym zapytaniu funkcja STUFF służy do usunięcia pierwszego przecinka
(,)
z wygenerowanego ciągu xml,(,aaa,bbb,ccc,ddd,eee)
po czym stanie się(aaa,bbb,ccc,ddd,eee)
.I
FOR XML PATH('')
po prostu konwertuje dane kolumny na(,aaa,bbb,ccc,ddd,eee)
ciąg, ale w PATH mijamy '', więc nie utworzy tagu XML.Na koniec pogrupowaliśmy rekordy za pomocą kolumny ID .
źródło
Debugowałem i w końcu zwróciłem moje „wypchane” zapytanie w normalny sposób.
Po prostu
daje mi zawartość tabeli do zapisania w tabeli dziennika z wyzwalacza, który debuguję.
źródło
źródło
STUFF ((WYBIERZ odrębny ',' + CAST (T.ID) FROM tabeli T, gdzie T.ID = 1 DLA ŚCIEŻKI XML ('')), 1,1, '') AS Nazwa
źródło
Często używam z klauzulą where
źródło