суббота, 14 июля 2012 г.

CSV с помощью T-SQL

Знакомы следующие вопросы
  • Как вывести значения в строку через запятую?
  • Как получить CSV (Comma Separated Values) из значений столбца?
Сформулируем проблему с помощью кода. Как имея следующие
CREATE TABLE [Data](
  [objectId] [int] NOT NULL
 ,[value] varchar(10) NOT NULL

);
GO

insert into [Data] ([objectId], [value])
          select 1, 'A'
union all select 1, 'B'
union all select 1, 'C'

union all select 2, '11'
union all select 2, '22'
union all select 2, '33'

union all select 3, 'Tom'
union all select 3, 'and'
union all select 3, 'Jerry'
получить такой результат?
--objectId    csv
------------- --------------
--1           A,B,C
--2           11,22,33
--3           Tom,and,Jerry
Порой мне кажется, что это одна из самых простых и часто встречаемых задач, которая заставляет разработчик лезть в google. Под катом решение этой задачи.
Решение опирается на возможности платформы работы с xml.
select 
select 
[objectId],
(
 select [Data].[value]
 from [Data]
 where [Data].[objectId] = D.[objectId]
 for xml path('')
) [csv]
from [Data] D
group by [objectId]

----------------------------
--objectId    csv
------------- --------------
--1           ABC
--2           112233
--3           TomandJerry

Как видно мы уже получили почти то что нам нужно, осталось только разделить результат запятыми. Для этого мы к [Data].[value] добавим запятую слева и воспользуемся функцией STUFF
select 
select 
[objectId],
stuff((
 select ','+[Data].[value]
 from [Data]
 where [Data].[objectId] = D.[objectId]
 for xml path('')
),1,1,'') [csv]
from [Data] D
group by [objectId]

--objectId    csv
------------- -------------
--1           A,B,C
--2           11,22,33
--3           Tom,and,Jerry

Доп. возможности

Можно управлять порядком, в котором данные будут попадать в строку
select 
[objectId],
stuff((
 select ','+[Data].[value]
 from [Data]
 where [Data].[objectId] = D.[objectId]
 order by [Data].[value]
 for xml path('')
),1,1,'') [csv]
from [Data] D
group by [objectId]
Сортировать можно не только по полю, которое попадает в строку, но и по другим полям, не попадающим в результирующий набор.

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

Отправить комментарий