Рассмотрим таблицу базы данных с именами из трех строк:
Peter
Paul
Mary
Есть ли простой способ превратить это в одну строку Peter, Paul, Mary
?
Рассмотрим таблицу базы данных с именами из трех строк:
Peter
Paul
Mary
Есть ли простой способ превратить это в одну строку Peter, Paul, Mary
?
Ответы:
Если вы используете SQL Server 2017 или Azure, см. Ответ Матье Ренда .
У меня была похожая проблема, когда я пытался соединить две таблицы с отношениями один-ко-многим. В SQL 2005 я обнаружил, что
XML PATH
метод может очень легко обрабатывать конкатенацию строк.Если есть таблица с именем
STUDENTS
Результат, который я ожидал, был:
Я использовал следующее
T-SQL
:Вы можете сделать то же самое более компактным способом, если вы можете объединить запятые в начале и использовать
substring
для пропуска первого, чтобы вам не нужно было выполнять подзапрос:источник
<
или&
. Смотрите комментарий @ BenHinman.FOR XML PATH ('')
. Это означает, что он не должен считаться надежным, поскольку любое исправление или обновление может изменить его функционирование. Это в основном полагаться на устаревшую функцию.FOR XML
он предназначен для генерации XML, а не для конкатенации произвольных строк. Вот почему она ускользает&
,<
и>
кодов XML сущностей (&
,<
,>
). Я предполагаю, что это также сбежит"
и'
в"
и'
в атрибутах также. Это неGROUP_CONCAT()
,string_agg()
,array_agg()
,listagg()
и т.д. , даже если вы можете отчасти сделать его сделать это. Мы должны тратить наше время, требуя, чтобы Microsoft реализовала правильную функцию.string_agg
в v.Next. и все это может уйти.Используйте
COALESCE
:Просто некоторое объяснение (так как этот ответ, кажется, получает относительно регулярные взгляды):
1) Нет необходимости инициализировать
@Names
пустым строковым значением.2) Нет необходимости снимать дополнительный разделитель в конце.
@Names
значение NULL после этой строки, а следующая строка снова будет начинаться как пустая строка. Легко исправляется одним из двух решения:или:
В зависимости от того, какое поведение вы хотите (первая опция просто отфильтровывает значения NULL , вторая опция сохраняет их в списке с сообщением-маркером [замените 'N / A' тем, что вам подходит]).
источник
SQL Server 2017+ и SQL Azure: STRING_AGG
Начиная со следующей версии SQL Server, мы можем, наконец, объединить строки, не прибегая к каким-либо переменным или XML-вехам.
STRING_AGG (Transact-SQL)
Без группировки
С группировкой:
С группировкой и суб-сортировкой
источник
Один метод, еще не показанный с помощью
XML
data()
команды в MS SQL Server:Предположим, таблица с именем NameList с одним столбцом с именем FName,
возвращает:
Только лишняя запятая должна быть обработана.
Редактировать: как принято из комментария @ NReilingh, вы можете использовать следующий метод для удаления запятой. Предполагая одинаковые имена таблиц и столбцов:
источник
+ ', '
он добавляет один пробел между каждым объединенным элементом.SELECT STUFF(REPLACE((SELECT '#!'+city AS 'data()' FROM #cityzip FOR XML PATH ('')),' #!',', '),1,2,'')
В SQL Server 2005
В SQL Server 2016
Вы можете использовать синтаксис FOR JSON
т.е.
И результат станет
Это будет работать, даже если ваши данные содержат недопустимые символы XML
'"},{"_":"'
безопасно , потому что, если ваши данные содержат'"},{"_":"',
будет убежал в"},{\"_\":\"
Вы можете заменить
', '
любой разделитель строкА в SQL Server 2017 база данных SQL Azure
Вы можете использовать новую функцию STRING_AGG
источник
<
,>
,&
и т.д. , которыеFOR XML PATH('')
будут автоматически избежать.В MySQL есть функция, GROUP_CONCAT () , которая позволяет объединять значения из нескольких строк. Пример:
источник
SEPARATOR '", "'
я пропущу некоторые символы в конце последней записи. почему это может случиться?CHAR
, вам нужно привести его, например, черезGROUP_CONCAT( CAST(id AS CHAR(8)) ORDER BY id ASC SEPARATOR ',')
2) если у вас будет много значений, вы должны увеличитьgroup_concat_max_len
как написано в stackoverflow.com/a/1278210/1498405Используйте COALESCE - узнайте больше здесь
Для примера:
Затем напишите ниже код в SQL Server,
Выход будет:
источник
Declare @Numbers AS Nvarchar(MAX)
и это работало нормально. Можете ли вы объяснить, почему вы рекомендуете не использовать его, пожалуйста?Массивы Postgres потрясающие. Пример:
Создайте некоторые тестовые данные:
Объедините их в массив:
Преобразуйте массив в строку с разделителями-запятыми:
СДЕЛАННЫЙ
Начиная с PostgreSQL 9.0 это еще проще .
источник
select array_to_string(array_agg(name||'('||id||')'
Oracle 11g Release 2 поддерживает функцию LISTAGG. Документация здесь .
Предупреждение
Будьте осторожны при реализации этой функции, если есть вероятность, что результирующая строка превысит 4000 символов. Это бросит исключение. Если это так, то вам нужно либо обработать исключение, либо выполнить собственную функцию, которая не позволяет объединенной строке превышать 4000 символов.
источник
LISTAGG
работает отлично! Просто прочитайте документ, связанный здесь.wm_concat
удалено с версии 12c и выше.В SQL Server 2005 и более поздних версиях используйте запрос ниже для объединения строк.
источник
<
или&
.У меня нет доступа к SQL Server дома, поэтому я предполагаю синтаксис здесь, но он более или менее:
источник
SELECT @names = @names + CASE WHEN LEN(@names)=0 THEN '' ELSE ' ' END + Name FROM Names
SELECT @names = @names + ISNULL(' ' + Name, '')
Было предложено рекурсивное решение CTE, но код не был предоставлен. Код ниже является примером рекурсивного CTE. Обратите внимание, что хотя результаты совпадают с вопросом, данные не совсем соответствуют заданному описанию, так как я предполагаю, что вы действительно хотите делать это для групп строк, а не для всех строк в таблице. Изменение его для соответствия всем строкам таблицы оставлено читателю в качестве упражнения.
источник
name
столбец в разделенных запятыми строку на 4 группы вid
с. На первый взгляд, я думаю, что это больше работы, чем большинство других решений для SQL Server.Начиная с PostgreSQL 9.0 это довольно просто:
В версиях до 9.0
array_agg()
может использоваться как показано hgmnzисточник
SELECT string_agg(non_text_type::text, ',') FROM table
varchar
илиchar
Вам нужно создать переменную, в которой будет храниться ваш конечный результат, и выбрать его, вот так.
Самое простое решение
источник
В SQL Server vNext это будет встроено с помощью функции STRING_AGG, подробнее об этом здесь: https://msdn.microsoft.com/en-us/library/mt790580.aspx
источник
Использование XML помогло мне получить строки, разделенные запятыми. Для дополнительной запятой мы можем использовать функцию замены SQL Server. Вместо добавления запятой использование AS data () объединит строки с пробелами, которые впоследствии можно будет заменить на запятые в качестве синтаксиса, приведенного ниже.
источник
Готовое решение без лишних запятых:
Пустой список приведет к значению NULL. Обычно вы вставляете список в столбец таблицы или переменную программы: установите максимальную длину 255 в соответствии с вашими потребностями.
(Дивакар и Йенс Франдсен дали хорошие ответы, но нуждаются в улучшении.)
источник
', '
на,','
если вам не нужно дополнительное место.Вот пример:
источник
Это ставит случайную запятую в начале.
Однако, если вам нужны другие столбцы или для CSV дочерней таблицы, вам нужно обернуть это в скалярное пользовательское поле (UDF).
Вы можете использовать XML-путь как коррелированный подзапрос в предложении SELECT (но мне придется подождать, пока я не вернусь к работе, потому что Google не выполняет работу дома :-)
источник
С другими ответами человек, читающий ответ, должен знать конкретную таблицу предметной области, такую как автомобиль или студент. Таблица должна быть создана и заполнена данными, чтобы протестировать решение.
Ниже приведен пример, в котором используется таблица «Information_Schema.Columns» SQL Server. Используя это решение, не нужно создавать таблицы или добавлять данные. В этом примере создается список имен столбцов, разделенных запятыми, для всех таблиц в базе данных.
источник
Для БД Oracle посмотрите этот вопрос: Как можно объединить несколько строк в одну в Oracle без создания хранимой процедуры?
Наилучшим ответом, по-видимому, является @Emmanuel, использующий встроенную функцию LISTAGG (), доступную в Oracle 11g Release 2 и более поздних версиях.
как указал @ user762952, и в соответствии с документацией Oracle http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php , функция WM_CONCAT () также является опцией. Это кажется стабильным, но Oracle явно не рекомендует использовать его для любого приложения SQL, поэтому используйте его на свой страх и риск.
Помимо этого, вам придется написать свою собственную функцию; В приведенном выше документе Oracle есть руководство, как это сделать.
источник
Чтобы избежать нулевых значений, вы можете использовать CONCAT ()
источник
Мне очень понравилась элегантность ответа Даны . Просто хотел сделать это завершенным.
источник
SELECT @names = @names + CASE WHEN LEN(@names)=0 THEN '' ELSE ', ' END + Name FROM Names
потом не нужно было его усекать.Этот ответ потребует некоторых привилегий на сервере для работы.
Сборки - это хороший вариант для вас. Есть много сайтов, которые объясняют, как его создать. Один я думаю , что очень хорошо объяснил это один
Если вы хотите, я уже создал сборку, и можно скачать DLL здесь .
Как только вы загрузите его, вам нужно будет запустить следующий скрипт на вашем SQL Server:
Обратите внимание, что путь к сборке может быть доступен для сервера. Поскольку вы успешно выполнили все шаги, вы можете использовать такую функцию, как:
Надеюсь, поможет!!!
источник
MySQL complete Пример:
У нас есть Пользователи, у которых может быть много Данных, и мы хотим иметь вывод, где мы можем видеть все пользовательские Данные в списке:
Результат:
Настройка таблицы:
Запрос:
источник
Я обычно использую select следующим образом, чтобы объединить строки в SQL Server:
источник
Если вы хотите иметь дело с пустыми значениями, вы можете сделать это, добавив предложение where или добавив еще один COALESCE вокруг первого.
источник
Это сработало для меня ( SqlServer 2016 ):
Вот источник: https://www.mytecbits.com/
И решение для MySql (поскольку эта страница отображается в Google для MySql)
Из документации MySql
источник
В Oracle это так
wm_concat
. Я считаю, что эта функция доступна в версии 10g и выше.источник
Это тоже может быть полезно
возвращается
источник