Как я могу объединить несколько строк в список, разделенный запятыми, в SQL Server 2005?

#sql #sql-server #list #function #concatenation

Вопрос:

Прямо сейчас у меня есть такой SQL-запрос, как этот:

 SELECT X, Y FROM POINTS
 

Он возвращает результаты примерно так:

 X    Y
----------
12   3
15   2
18   12
20   29
 

Я хотел бы возвращать результаты в одной строке, вот так (подходит для использования в теге HTML <ОБЛАСТЬ>):

 XYLIST
----------
12,3,15,2,18,12,20,29
 

Есть ли способ сделать это, используя только SQL?

Комментарии:

1. Если вы хотите, чтобы ваше приложение масштабировалось, было бы лучше делать такие вещи за пределами базы данных. База данных почти всегда будет вашим узким местом.

2. Интересно, почему хороший ответ исчез?

3. @Джозеф Буй — Поверь мне, я знаю. К сожалению, руководитель проекта настаивает, чтобы я делал это таким образом.

Ответ №1:

Спасибо за быстрые и полезные ответы, ребята!

Я просто нашел еще один быстрый способ сделать это тоже:

 SELECT  STUFF(( SELECT ','   X   ','   Y
                FROM Points
              FOR
                XML PATH('')
              ), 1, 1, '') AS XYList
 

Заслуга этого парня:

http://geekswithblogs.net/mnf/archive/2007/10/02/t-sql-user-defined-function-to-concatenate-column-to-csv-string.aspx

Комментарии:

1. Мне действительно больше всего нравится это решение. Простой в использовании и только одна строка для добавления в любой SQL.

2. Примечание. Этот метод приводит к замене специальных символов их XML-эквивалентом. ИОУ, Барнс и Нобл становятся Барнсом и Ноблом

Ответ №2:

 DECLARE @XYList varchar(MAX)
SET @XYList = ''

SELECT @XYList = @XYList   CONVERT(varchar, X)   ','   CONVERT(varchar, Y)   ','
FROM POINTS

-- Remove last comma
SELECT LEFT(@XYList, LEN(@XYList) - 1)
 

Комментарии:

1. Мне кажется, или это не работает на связанном сервере? Когда я пытаюсь сделать что-то подобное SELECT @List = @List CONVERT(varchar, ID) ',' FROM LinkedServer.MyDatabase.dbo.MyTable , он всегда возвращает только один идентификатор. A Select * возвращает множество идентификаторов.

Ответ №3:

Используя этот COALESCE трюк, вам не нужно беспокоиться о конечной запятой:

 DECLARE @XYList AS varchar(MAX) -- Leave as NULL

SELECT @XYList = COALESCE(@XYList   ',', '')   CONVERT(varchar, X)   ','   CONVERT(varchar, Y)
FROM POINTS
 

Ответ №4:

Начиная с SQL 2017, вы можете использовать STRING_AGG

 SELECT STRING_AGG (X   ','   Y, ',') AS XYLIST
FROM POINTS
 

https://docs.microsoft.com/en-us/sql/t-sql/functions/string-agg-transact-sql?view=sql-server-2017

Ответ №5:

 DECLARE @s VarChar(8000)
SET @s = ''

SELECT @s = @s   ','   CAST(X AS VarChar)   ','   CAST(Y AS VarChar) 
FROM POINTS

SELECT @s 
 

Просто избавьтесь от ведущей запятой