Jak połączyć tekst z wielu wierszy w jeden ciąg tekstowy w SQL server?
Rozważmy tabelę bazy danych zawierającą nazwy, z trzema wierszami:
Peter
Paul
Mary
Czy jest łatwy sposób na przekształcenie tego w pojedynczy ciąg Peter, Paul, Mary
?
30 answers
Jeśli korzystasz z SQL Server 2017 lub Azure, zobacz Mathieu Renda answer.
Miałem podobny problem, gdy próbowałem połączyć dwa stoły z relacji jeden do wielu. W SQL 2005 odkryłem, że metoda XML PATH
bardzo łatwo radzi sobie z konkatenacją wierszy.
Jeśli istnieje tabela o nazwie STUDENTS
SubjectID StudentName
---------- -------------
1 Mary
1 John
1 Sam
2 Alaina
2 Edward
Oczekiwałem wyniku:
SubjectID StudentName
---------- -------------
1 Mary, John, Sam
2 Alaina, Edward
Użyłem następującego T-SQL
:
SELECT Main.SubjectID,
LEFT(Main.Students,Len(Main.Students)-1) As "Students"
FROM
(
SELECT DISTINCT ST2.SubjectID,
(
SELECT ST1.StudentName + ',' AS [text()]
FROM dbo.Students ST1
WHERE ST1.SubjectID = ST2.SubjectID
ORDER BY ST1.SubjectID
FOR XML PATH ('')
) [Students]
FROM dbo.Students ST2
) [Main]
Można zrobić to samo w bardziej zwarty sposób, jeśli można concat przecinki na początku i użyj substring
, aby pominąć pierwszy, więc nie musisz wykonywać pod-zapytania:
SELECT DISTINCT ST2.SubjectID,
SUBSTRING(
(
SELECT ','+ST1.StudentName AS [text()]
FROM dbo.Students ST1
WHERE ST1.SubjectID = ST2.SubjectID
ORDER BY ST1.SubjectID
FOR XML PATH ('')
), 2, 1000) [Students]
FROM dbo.Students ST2
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-02 11:20:52
Ta odpowiedź może zwrócić nieoczekiwane wyniki, gdy występuje klauzula ORDER BY. Aby uzyskać spójne wyniki, użyj jednej z metod ścieżki for XML wyszczególnionych w innych odpowiedziach.
Użycie COALESCE
:
DECLARE @Names VARCHAR(8000)
SELECT @Names = COALESCE(@Names + ', ', '') + Name
FROM People
Tylko jakieś wyjaśnienie (ponieważ ta odpowiedź wydaje się mieć stosunkowo regularne odsłony):
- Coalesce jest tak naprawdę tylko pomocnym oszustwem, które osiąga dwie rzeczy:]}
1) nie ma potrzeby inicjalizacji @Names
z pustą wartością łańcuchową.
2) nie ma potrzeby zdejmowania dodatkowego separatora na końcu.
- powyższe rozwiązanie da nieprawidłowe wyniki, jeśli wiersz ma NULL wartość nazwy (jeśli istnieje NULL , NULL spowoduje
@Names
NULL Po tym wierszu, a następny wiersz zacznie się od nowa jako pusty łańcuch. Łatwo naprawić za pomocą jednego z dwóch rozwiązań:
DECLARE @Names VARCHAR(8000)
SELECT @Names = COALESCE(@Names + ', ', '') + Name
FROM People
WHERE Name IS NOT NULL
Lub:
DECLARE @Names VARCHAR(8000)
SELECT @Names = COALESCE(@Names + ', ', '') +
ISNULL(Name, 'N/A')
FROM People
W zależności od zachowania (pierwsza opcja filtruje NULLs out, druga opcja utrzymuje je na liście z Komunikatem znacznika [zamień "N / A" na to, co jest odpowiednie dla Ciebie]).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-30 09:26:56
Jedna metoda jeszcze nie pokazana przez XML
data()
polecenie w MS SQL Server to:
Przyjmij tabelę nazwaną listą nazw z jedną kolumną nazwaną FName,
SELECT FName + ', ' AS 'data()'
FROM NameList
FOR XML PATH('')
Zwraca:
"Peter, Paul, Mary, "
Tylko dodatkowy przecinek musi być rozpatrywany.
Edit: jak przyjęto z komentarza @NReilingh, możesz użyć następującej metody, aby usunąć końcowy przecinek. Zakładając te same nazwy tabeli i kolumn:
STUFF(REPLACE((SELECT '#!' + LTRIM(RTRIM(FName)) AS 'data()' FROM NameList
FOR XML PATH('')),' #!',', '), 1, 2, '') as Brands
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-25 15:28:47
In SQL Server 2005
SELECT Stuff(
(SELECT N', ' + Name FROM Names FOR XML PATH(''),TYPE)
.value('text()[1]','nvarchar(max)'),1,2,N'')
W SQL Server 2016
Możesz użyć dla składni JSON
Tzn.
SELECT per.ID,
Emails = JSON_VALUE(
REPLACE(
(SELECT _ = em.Email FROM Email em WHERE em.Person = per.ID FOR JSON PATH)
,'"},{"_":"',', '),'$[0]._'
)
FROM Person per
I wynik będzie
Id Emails
1 [email protected]
2 NULL
3 [email protected], [email protected]
To zadziała nawet Twoje dane zawierają nieprawidłowe znaki XML
'"},{"_":"'
jest bezpieczny, ponieważ jeśli dane zawierają '"},{"_":"',
zostanie on zabezpieczony "},{\"_\":\"
Możesz zastąpić ', '
dowolnym separatorem łańcuchów
I w SQL Server 2017, Azure SQL Baza danych
Możesz użyć nowej funkcji STRING_AGG
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-23 16:55:05
SQL Server 2017 + i SQL Azure: STRING_AGG
Zaczynając od następnej wersji SQL Server, możemy w końcu łączyć wiersze bez konieczności uciekania się do jakiejkolwiek zmiennej lub XML.
Bez grupowania
SELECT STRING_AGG(Name, ', ') AS Departments
FROM HumanResources.Department;
Z grupowaniem:
SELECT GroupName, STRING_AGG(Name, ', ') AS Departments
FROM HumanResources.Department
GROUP BY GroupName;
Z grupowaniem i sortowaniem podrzędnym
SELECT GroupName, STRING_AGG(Name, ', ') WITHIN GROUP (ORDER BY Name ASC) AS Departments
FROM HumanResources.Department
GROUP BY GroupName;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-24 05:36:45
W MySQL istnieje funkcja GROUP_CONCAT () , która pozwala na łączenie wartości z wielu wierszy. Przykład:
SELECT 1 AS a, GROUP_CONCAT(name ORDER BY name ASC SEPARATOR ', ') AS people
FROM users
WHERE id IN (1,2,3)
GROUP BY a
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-26 18:37:58
Użycie COALESCE - dowiedz się więcej tutaj
dla przykładu:
102
103
104
Następnie wpisz poniżej kod w SQL server,
Declare @Numbers AS Nvarchar(MAX) -- It must not be MAX if you have few numbers
SELECT @Numbers = COALESCE(@Numbers + ',', '') + Number
FROM TableName where Number IS NOT NULL
SELECT @Numbers
Wyjście będzie:
102,103,104
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-22 23:27:27
Oracle 11g Release 2 obsługuje funkcję LISTAGG. Dokumentacja Tutaj .
COLUMN employees FORMAT A50
SELECT deptno, LISTAGG(ename, ',') WITHIN GROUP (ORDER BY ename) AS employees
FROM emp
GROUP BY deptno;
DEPTNO EMPLOYEES
---------- --------------------------------------------------
10 CLARK,KING,MILLER
20 ADAMS,FORD,JONES,SCOTT,SMITH
30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD
3 rows selected.
Ostrzeżenie
Bądź ostrożny w implementacji tej funkcji, jeśli istnieje możliwość, że wynikowy ciąg znaków przekracza 4000 znaków. To spowoduje wyjątek. Jeśli tak jest, musisz albo obsłużyć wyjątek, albo wywinąć własną funkcję, która zapobiega ciągowi łączącemu przekraczającemu 4000 znaków.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-14 14:30:15
Tablice Postgres są niesamowite. Przykład:
Utwórz dane testowe:
postgres=# \c test
You are now connected to database "test" as user "hgimenez".
test=# create table names (name text);
CREATE TABLE
test=# insert into names (name) values ('Peter'), ('Paul'), ('Mary');
INSERT 0 3
test=# select * from names;
name
-------
Peter
Paul
Mary
(3 rows)
Połącz je w tablicę:
test=# select array_agg(name) from names;
array_agg
-------------------
{Peter,Paul,Mary}
(1 row)
Konwertuj tablicę na łańcuch rozdzielany przecinkami:
test=# select array_to_string(array_agg(name), ', ') from names;
array_to_string
-------------------
Peter, Paul, Mary
(1 row)
Zrobione
Od PostgreSQL 9.0 jest to jeszcze łatwiejsze.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:33
W SQL Server 2005 i nowszych, użyj poniższego zapytania, aby połączyć wiersze.
DECLARE @t table
(
Id int,
Name varchar(10)
)
INSERT INTO @t
SELECT 1,'a' UNION ALL
SELECT 1,'b' UNION ALL
SELECT 2,'c' UNION ALL
SELECT 2,'d'
SELECT ID,
stuff(
(
SELECT ','+ [Name] FROM @t WHERE Id = t.Id FOR XML PATH('')
),1,1,'')
FROM (SELECT DISTINCT ID FROM @t ) t
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-20 08:49:30
Nie mam dostępu do serwera SQL w domu, więc domyślam się co do składni tutaj, ale jest mniej więcej:
DECLARE @names VARCHAR(500)
SELECT @names = @names + ' ' + Name
FROM Names
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-12 00:16:20
Zaproponowano rekurencyjne rozwiązanie CTE, ale nie dostarczono kodu. Poniższy kod jest przykładem rekurencyjnego CTE-zauważ, że chociaż wyniki pasują do pytania, dane nie pasują do podanego opisu, ponieważ zakładam, że naprawdę chcesz to robić na grupach wierszy, a nie wszystkich wierszy w tabeli. Zmiana go, aby pasował do wszystkich wierszy w tabeli, jest pozostawiona jako ćwiczenie dla czytelnika.
;with basetable as
( SELECT id, CAST(name as varchar(max))name,
ROW_NUMBER() OVER(Partition By id order by seq) rw,
COUNT(*) OVER (Partition By id) recs
FROM (VALUES (1, 'Johnny', 1), (1,'M', 2),
(2,'Bill', 1), (2, 'S.', 4), (2, 'Preston', 5), (2, 'Esq.', 6),
(3, 'Ted', 1), (3,'Theodore', 2), (3,'Logan', 3),
(4, 'Peter', 1), (4,'Paul', 2), (4,'Mary', 3)
)g(id, name, seq)
),
rCTE as (
SELECT recs, id, name, rw from basetable where rw=1
UNION ALL
SELECT b.recs, r.ID, r.name +', '+ b.name name, r.rw+1
FROM basetable b
inner join rCTE r
on b.id = r.id and b.rw = r.rw+1
)
SELECT name FROM rCTE
WHERE recs = rw and ID=4
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-09 21:06:05
Począwszy od PostgreSQL 9.0 jest to dość proste:
select string_agg(name, ',')
from names;
W wersjach przed 9.0 array_agg()
może być używany zgodnie z hgmnz
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-20 10:42:42
Musisz utworzyć zmienną, która będzie przechowywać wynik końcowy i wybrać do niej, w ten sposób.
Najprostsze Rozwiązanie
DECLARE @char VARCHAR(MAX);
SELECT @char = COALESCE(@char + ', ' + [column], [column])
FROM [table];
PRINT @char;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-15 21:07:57
W Sql Server vNext będzie to wbudowane w funkcję STRING_AGG, przeczytaj więcej o tym tutaj: https://msdn.microsoft.com/en-us/library/mt790580.aspx
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-10 15:42:49
Using XML helped me in getting rows separated with commas. Dla dodatkowego przecinka możemy użyć funkcji replace serwera SQL. Zamiast dodawania przecinka, użycie as' data () ' połączy wiersze ze spacjami, które później można zastąpić przecinkami w składni zapisanej poniżej.
REPLACE(
(select FName AS 'data()' from NameList for xml path(''))
, ' ', ', ')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-26 18:42:55
Gotowe do użycia rozwiązanie, bez dodatkowych przecinków:
select substring(
(select ', '+Name AS 'data()' from Names for xml path(''))
,3, 255) as "MyList"
Pusta lista spowoduje wartość NULL. Zwykle wstawisz listę do kolumny tabeli lub zmiennej programu: dostosuj maksymalną długość 255 do swoich potrzeb.
(Diwakar i Jens Frandsen dostarczyli dobrych odpowiedzi, ale potrzebują poprawy.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-26 20:03:20
DECLARE @Names VARCHAR(8000)
SELECT @name = ''
SELECT @Names = @Names + ',' + Names FROM People
SELECT SUBSTRING(2, @Names, 7998)
To stawia bezpański przecinek na początku.
Jeśli jednak potrzebujesz innych kolumn lub tabeli potomnej CSV, musisz ją zawinąć w skalarne pole zdefiniowane przez użytkownika (UDF).
Możesz również użyć ścieżki XML jako skorelowanego zapytania podrzędnego w klauzuli SELECT (ale musiałbym poczekać, aż wrócę do pracy, ponieważ Google nie robi rzeczy roboczych w domu: -)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-26 18:39:58
Z innymi odpowiedziami, osoba czytająca odpowiedź musi być świadoma określonej tabeli domen, takiej jak pojazd lub uczeń. Tabelę należy utworzyć i uzupełnić danymi w celu przetestowania rozwiązania.
Poniżej znajduje się przykład, który używa SQL Server "Information_Schema.Kolumny " tabela. Dzięki temu rozwiązaniu nie trzeba tworzyć tabel ani dodawać danych. Ten przykład tworzy oddzieloną przecinkami listę nazw kolumn dla wszystkich tabel w bazie danych.
SELECT
Table_Name
,STUFF((
SELECT ',' + Column_Name
FROM INFORMATION_SCHEMA.Columns Columns
WHERE Tables.Table_Name = Columns.Table_Name
ORDER BY Column_Name
FOR XML PATH ('')), 1, 1, ''
)Columns
FROM INFORMATION_SCHEMA.Columns Tables
GROUP BY TABLE_NAME
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-04 19:31:22
SELECT STUFF((SELECT ', ' + name FROM [table] FOR XML PATH('')), 1, 2, '')
Oto przykład:
DECLARE @t TABLE (name VARCHAR(10))
INSERT INTO @t VALUES ('Peter'), ('Paul'), ('Mary')
SELECT STUFF((SELECT ', ' + name FROM @t FOR XML PATH('')), 1, 2, '')
--Peter, Paul, Mary
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-28 16:04:05
Dla Oracle DBs, zobacz to pytanie: Jak wiele wierszy może być połączonych w jeden w Oracle bez tworzenia procedury składowanej?
Najlepszą odpowiedzią wydaje się być @Emmanuel, używając wbudowanej funkcji LISTAGG (), dostępnej w Oracle 11g Release 2 i nowszych.
SELECT question_id,
LISTAGG(element_id, ',') WITHIN GROUP (ORDER BY element_id)
FROM YOUR_TABLE;
GROUP BY question_id
Jak zauważył @user762952 i zgodnie z dokumentacją Oracle http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php , funkcja WM_CONCAT() jest również opcja. Wydaje się stabilny, ale Oracle wyraźnie zaleca używanie go dla dowolnej aplikacji SQL, więc używaj go na własne ryzyko.
Poza tym będziesz musiał napisać własną funkcję; powyższy dokument Oracle zawiera przewodnik, Jak to zrobić.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:36
Aby uniknąć wartości null, możesz użyć CONCAT ()
DECLARE @names VARCHAR(500)
SELECT @names = CONCAT(@names, ' ', name)
FROM Names
select @names
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-12 12:01:27
Ta odpowiedź będzie wymagała pewnych uprawnień na serwerze do działania.
Zespoły są dobrym rozwiązaniem dla Ciebie. Istnieje wiele witryn, które wyjaśniają, jak go utworzyć. Myślę, że bardzo dobrze wyjaśnione jest to jeden
Jeśli chcesz, Mam już utworzony assembly i można pobrać DLL tutaj .
Po pobraniu go, będziesz musiał uruchomić następujący skrypt na serwerze SQL:
CREATE Assembly concat_assembly
AUTHORIZATION dbo
FROM '<PATH TO Concat.dll IN SERVER>'
WITH PERMISSION_SET = SAFE;
GO
CREATE AGGREGATE dbo.concat (
@Value NVARCHAR(MAX)
, @Delimiter NVARCHAR(4000)
) RETURNS NVARCHAR(MAX)
EXTERNAL Name concat_assembly.[Concat.Concat];
GO
sp_configure 'clr enabled', 1;
RECONFIGURE
Zauważ, że ścieżka do montażu może być dostępna dla serwera. Ponieważ pomyślnie wykonałeś wszystkie kroki, możesz użyć funkcji takiej jak:
SELECT dbo.Concat(field1, ',')
FROM Table1
Mam nadzieję, że to pomoże!!!Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-08 01:39:06
Kompletny przykład MySQL:
Mamy Użytkowników, którzy mogą mieć wiele danych i chcemy mieć wyjście, gdzie możemy zobaczyć wszystkie dane użytkowników na liście:
Wynik:
___________________________
| id | rowList |
|-------------------------|
| 0 | 6, 9 |
| 1 | 1,2,3,4,5,7,8,1 |
|_________________________|
Ustawienie Tabeli:
CREATE TABLE `Data` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
INSERT INTO `Data` (`id`, `user_id`) VALUES
(1, 1),
(2, 1),
(3, 1),
(4, 1),
(5, 1),
(6, 0),
(7, 1),
(8, 1),
(9, 0),
(10, 1);
CREATE TABLE `User` (
`id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `User` (`id`) VALUES
(0),
(1);
Query:
SELECT User.id, GROUP_CONCAT(Data.id ORDER BY Data.id) AS rowList FROM User LEFT JOIN Data ON User.id = Data.user_id GROUP BY User.id
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-22 07:51:12
Bardzo podobała mi się elegancja odpowiedzi Dana. Chciałem go tylko dopełnić.
DECLARE @names VARCHAR(MAX)
SET @names = ''
SELECT @names = @names + ', ' + Name FROM Names
-- Deleting last two symbols (', ')
SET @sSql = LEFT(@sSql, LEN(@sSql) - 1)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:19
Zwykle używam select w ten sposób do łączenia łańcuchów w SQL Server:
with lines as
(
select
row_number() over(order by id) id, -- id is a line id
line -- line of text.
from
source -- line source
),
result_lines as
(
select
id,
cast(line as nvarchar(max)) line
from
lines
where
id = 1
union all
select
l.id,
cast(r.line + N', ' + l.line as nvarchar(max))
from
lines l
inner join
result_lines r
on
l.id = r.id + 1
)
select top 1
line
from
result_lines
order by
id desc
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-06 07:06:01
To też może być przydatne
create table #test (id int,name varchar(10))
--use separate inserts on older versions of SQL Server
insert into #test values (1,'Peter'), (1,'Paul'), (1,'Mary'), (2,'Alex'), (3,'Jack')
DECLARE @t VARCHAR(255)
SELECT @t = ISNULL(@t + ',' + name, name) FROM #test WHERE id = 1
select @t
drop table #test
Zwraca
Peter,Paul,Mary
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-25 08:14:23
Jeśli chcesz radzić sobie z nullami, możesz to zrobić dodając klauzulę where lub dodać kolejną KOALESCE wokół pierwszej.
DECLARE @Names VARCHAR(8000)
SELECT @Names = COALESCE(COALESCE(@Names + ', ', '') + Name, @Names) FROM People
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-27 20:05:13
W Oracle jest to wm_concat
. Wydaje mi się, że ta funkcja jest dostępna w wersji 10g i wyższej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-26 18:44:21
--SQL Server 2005 +
CREATE TABLE dbo.Students
(
StudentId INT
, Name VARCHAR(50)
, CONSTRAINT PK_Students PRIMARY KEY (StudentId)
);
CREATE TABLE dbo.Subjects
(
SubjectId INT
, Name VARCHAR(50)
, CONSTRAINT PK_Subjects PRIMARY KEY (SubjectId)
);
CREATE TABLE dbo.Schedules
(
StudentId INT
, SubjectId INT
, CONSTRAINT PK__Schedule PRIMARY KEY (StudentId, SubjectId)
, CONSTRAINT FK_Schedule_Students FOREIGN KEY (StudentId) REFERENCES dbo.Students (StudentId)
, CONSTRAINT FK_Schedule_Subjects FOREIGN KEY (SubjectId) REFERENCES dbo.Subjects (SubjectId)
);
INSERT dbo.Students (StudentId, Name) VALUES
(1, 'Mary')
, (2, 'John')
, (3, 'Sam')
, (4, 'Alaina')
, (5, 'Edward')
;
INSERT dbo.Subjects (SubjectId, Name) VALUES
(1, 'Physics')
, (2, 'Geography')
, (3, 'French')
, (4, 'Gymnastics')
;
INSERT dbo.Schedules (StudentId, SubjectId) VALUES
(1, 1) --Mary, Physics
, (2, 1) --John, Physics
, (3, 1) --Sam, Physics
, (4, 2) --Alaina, Geography
, (5, 2) --Edward, Geography
;
SELECT
sub.SubjectId
, sub.Name AS [SubjectName]
, ISNULL( x.Students, '') AS Students
FROM
dbo.Subjects sub
OUTER APPLY
(
SELECT
CASE ROW_NUMBER() OVER (ORDER BY stu.Name) WHEN 1 THEN '' ELSE ', ' END
+ stu.Name
FROM
dbo.Students stu
INNER JOIN dbo.Schedules sch
ON stu.StudentId = sch.StudentId
WHERE
sch.SubjectId = sub.SubjectId
ORDER BY
stu.Name
FOR XML PATH('')
) x (Students)
;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-01 20:42:40