Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Выборка в одну строку  [new]
izoldov-roskini
Member

Откуда:
Сообщений: 1169
Есть таблица, в ней значения:
Value1
Value2
...
Value N
Не могу сообразить как одним запросом получить строку вида Value1,Value2,...,Value N
Сделал при помощи курсора, все хорошо, но хотелось бы избежать его использования.
Или может использовать обощенное табличное выражение?
12 май 11, 18:07    [10643661]     Ответить | Цитировать Сообщить модератору
 Re: Выборка в одну строку  [new]
iljy
Member

Откуда:
Сообщений: 8711
izoldov-roskini,

PIVOT
12 май 11, 18:08    [10643666]     Ответить | Цитировать Сообщить модератору
 Re: Выборка в одну строку  [new]
iljy
Member

Откуда:
Сообщений: 8711
izoldov-roskini,

или вам что надо? Строки сложить чтоли? Тогда ФАК-сложение символьных полей в запросе.
12 май 11, 18:09    [10643670]     Ответить | Цитировать Сообщить модератору
 Re: Выборка в одну строку  [new]
izoldov-roskini
Member

Откуда:
Сообщений: 1169
да мне все строки из таблицы надо сложить и на выходе получить одну строку через запятую
12 май 11, 18:18    [10643723]     Ответить | Цитировать Сообщить модератору
 Re: Выборка в одну строку  [new]
Kamenyka
Member

Откуда:
Сообщений: 43
[url=]https://www.sql.ru/faq/faq_topic.aspx?fid=130 [/url] Там все доходчиво написано ;)
12 май 11, 18:20    [10643732]     Ответить | Цитировать Сообщить модератору
 Re: Выборка в одну строку  [new]
izoldov-roskini
Member

Откуда:
Сообщений: 1169
Ну в принципе тоже самое можно сделать и курсором
12 май 11, 18:24    [10643749]     Ответить | Цитировать Сообщить модератору
 Re: Выборка в одну строку  [new]
VGalamakh
Member

Откуда: Киев (Альба)
Сообщений: 66
как вариант

declare @s varchar(8000)
set @s=''

update a
set @s=@s+[name]+','
from phone a

Select @s

где [name] - имя вашего поля
12 май 11, 18:24    [10643752]     Ответить | Цитировать Сообщить модератору
 Re: Выборка в одну строку  [new]
Начинающий SQL 2008
Member

Откуда:
Сообщений: 438
VGalamakh,

Лучше использовать for xml path.
Через переменную скорость на больших данных низкая, да и если встретится столбец с null, то будет null
declare @s varchar(max)

declare @t table (naim varchar(100))
insert @t
 select 'v1' union all select 'v2' union all select 'v3' union all select null
 
select * from @t

set @s = ''
select @s = @s + ', ' + naim from @t --where naim is not null

select @s [@s]

-- Строка через xml path 1 (substring)
set statistics time on
select substring((select ', ' + naim from @t for xml path('')), 3, 2147483647) /* длина varchar(max) = 2147483647 байт */ [Строка через xml path 1 (substring)] 
set statistics time off

-- Строка через xml path 2 (stuff)
set statistics time on
select stuff((select ', ' + naim from @t for xml path('')), 1, 2, '') [Строка через xml path 2 (stuff)]
12 май 11, 19:03    [10643906]     Ответить | Цитировать Сообщить модератору
 Re: Выборка в одну строку  [new]
Начинающий SQL 2008
Member

Откуда:
Сообщений: 438
+ Кому интересно, тесты на скорость
set nocount on
declare @t table (account varchar(max))

;with cte (account, cnt) as
(
 select null,1 union all select 'account',1
 union all
 select account, cnt+1 from cte
 where cnt < 25000
)
insert @t
 select account +' '+ cast(row_number() over (order by (select 0)) as varchar) from cte
 order by cnt
 option (maxrecursion 0)

--select * from @t
set statistics time off


-- Для 2005+. Самый быстрый через xml path. Лишние символы удаляются через substring. Через stuff тоже быстро, проигрывает совсем чуть-чуть.
print 'Результаты через xml path. Самый быстрый способ'
print ''
print '[Строка через xml path 1 (substring)] '
set statistics time on
select substring((select ', ' + account from @t for xml path('')), 3, 2147483647) /* длина varchar(max) = 2147483647 байт */ [Строка через xml path 1 (substring)] 
set statistics time off
print ''
print ''
print ''
print '[Строка через xml path 2 (stuff)]'
set statistics time on
select stuff((select ', ' + account from @t for xml path('')), 1, 2, '') [Строка через xml path 2 (stuff)]
set statistics time off



-- Через накопительную переменную. Скорость ниже.'
print ''
print ''
print '----------------------------------------------------------------------------------------------------'
print 'Результаты через накопительную переменную. Скорость ниже.'
print ''
print 'Формирование самой строки'
declare @s varchar(max)
set statistics time on
select @s = isnull(@s + ', ', '') + account from @t where account is not null
select @s
set statistics time off
12 май 11, 19:05    [10643919]     Ответить | Цитировать Сообщить модератору
 Re: Выборка в одну строку  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Начинающий SQL 2008
for xml path
Что-то не видно
... FOR XML Path(''),Type).value('text()[1]','NVarChar(max)')),1 ...
Экранировать то надо на спец символы.
12 май 11, 22:12    [10644362]     Ответить | Цитировать Сообщить модератору
 Re: Выборка в одну строку  [new]
Начинающий SQL 2008
Member

Откуда:
Сообщений: 438
Mnior,
Согласен. Так правильнее:
declare @t table (naim varchar(100))
insert @t select '&<>=' union all select 'char(1)' union all select 'char(0)' union all select null
select * from @t

select substring((select ', ' + naim from @t for xml path(''),type).value('text()[1]','NVarChar(max)'), 3, 2147483647) /* длина varchar(max) = 2147483647 байт */ [Строка через xml path 1 (substring)] 

А есть рецепт для случая, если попадутся символы типа char(0), char(1) и т.д. ?
13 май 11, 10:26    [10645543]     Ответить | Цитировать Сообщить модератору
 Re: Выборка в одну строку  [new]
VGalamakh
Member

Откуда: Киев (Альба)
Сообщений: 66
Начинающий SQL 2008]VGalamakh,

Лучше использовать for xml path.
Через переменную скорость на больших данных низкая, да и если встретится столбец с null, то будет null


Да, for xml path выглядит поэффектней в плане скорости. Просто никогда не пользовался, попробую встроить себе в проэкты.
А касательно null то думаю, тут не составит большого труда в моем примере написать isnull([имя поля],0) или в конструкции Where
написать And [имя поля] is not null
13 май 11, 12:08    [10646531]     Ответить | Цитировать Сообщить модератору
 Re: Выборка в одну строку  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Начинающий SQL 2008
А есть рецепт для случая, если попадутся символы типа char(0), char(1) и т.д. ?
Опана. Хм.
А пробовали проверять?

База должная быть девственна технологически, категорически запрещать вход, и не мается фигнёй на выходе.
Т.е. ошибки решаются до и заранее.

VGalamakh
А касательно null то думаю
Нет никаких проблем с NULL - он игнорируется. В этом прелесть FOR XML - никаких CASE-ов не нужно.
Хотя у него есть свои побочные фишки (NULL AS [text()]).
13 май 11, 20:18    [10650410]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить