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

Откуда:
Сообщений: 83
Здравствуйте, есть таблица mssql из многих полей, отличающихся на 1.
Например, Ax,Bx,V,X1,X2,X3..Xn500
Как быстрее опросить строку из этих полей, чтобы на выходе была
склеенная строка из значений X1..Xn по разделителю, например, 5;4;4;6;9;5,
чтобы не создавать руками 500 переменных.
Спасибо.
5 сен 14, 16:44    [16541418]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
Glory
Member

Откуда:
Сообщений: 104751
select a1+';'+a2+';'+... +aN from mytable
5 сен 14, 16:45    [16541422]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
pegoopik
Member

Откуда: Новосибирск
Сообщений: 54
Igorgg,

Уточните вопрос:
Пример данных - что должно получиться на этом примере данных.
5 сен 14, 16:47    [16541441]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4846
Glory
select a1+';'+a2+';'+... +aN from mytable


Имейте ввиду, что если попадётся NULL, то весь результат станет NULL. Функция CONCAT на SQL 2012 лишена этого недостатка
5 сен 14, 16:51    [16541464]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
_djХомяГ
Guest
a_voronin
Glory
select a1+';'+a2+';'+... +aN from mytable


Имейте ввиду, что если попадётся NULL, то весь результат станет NULL. Функция CONCAT на SQL 2012 лишена этого недостатка

можно обойти настройкой set CONCAT_NULL_YIELDS_NULL
5 сен 14, 16:55    [16541492]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
Igorgg
Member

Откуда:
Сообщений: 83
Проблема как раз в том, что имеются NULL в строках и сервер не 12
5 сен 14, 16:56    [16541498]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
Glory
Member

Откуда:
Сообщений: 104751
a_voronin
Функция CONCAT на SQL 2012 лишена этого недостатка

А 500 параметров она осилит ?
5 сен 14, 16:56    [16541499]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
Igorgg
Member

Откуда:
Сообщений: 83
Тем более параметры float, нужно cast использовать
5 сен 14, 16:59    [16541519]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
churupaha
Member

Откуда: Краснодар
Сообщений: 1015
для чего? м. б. xquery сойдет.
5 сен 14, 16:59    [16541521]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
Igorgg
Member

Откуда:
Сообщений: 83
Руками тоже устанешь перечислять.
Нужен цикл в Transact sql для динамической строки, если нет NULL
5 сен 14, 17:00    [16541532]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
ГуЗы
Guest
:)

declare @ii int, @ss nvarchar(maX)
set @ii=2
set @ss = 'isnull(x1,'''')+'','''
while @ii<=50

begin
select  @ss=@ss+'+isnull('+'x'+cast(@ii as nvarchar)+','''')'
select @ii=@ii+1
end
select 'select '+ @ss +' from Table'
5 сен 14, 17:01    [16541537]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
pegoopik
Member

Откуда: Новосибирск
Сообщений: 54
Igorgg
Проблема как раз в том, что имеются NULL в строках и сервер не 12


SELECT STUFF(
    ISNULL(';' + X1, '') + ISNULL(';' + X2, '') + ... + ISNULL(';' + X500, '')
  , 1, 1, '')
5 сен 14, 17:05    [16541569]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4846
Glory
a_voronin
Функция CONCAT на SQL 2012 лишена этого недостатка

А 500 параметров она осилит ?


Это вопрос со смыслом или так троллинг?

Msg 189, Level 15, State 1, Line 1
The concat function requires 2 to 254 arguments.
5 сен 14, 17:19    [16541662]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4846
Но вложенный CONCAT никто не запретил

SELECT CONCAT(

CONCAT (
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL),


CONCAT (
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL),


CONCAT (
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL),


CONCAT (
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL),


CONCAT (
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL),


CONCAT (
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL),


CONCAT (
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL,
'A','B','C','D','E','1','2','3','4',NULL),


'')
5 сен 14, 17:20    [16541673]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
Glory
Member

Откуда:
Сообщений: 104751
a_voronin
Это вопрос со смыслом или так троллинг?

А вы как думаете ?

"X2,X3..Xn500" "чтобы не создавать руками 500 переменных."
5 сен 14, 17:21    [16541680]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
Igorgg
Member

Откуда:
Сообщений: 83
Надо теперь его под NULL исправить, чтобы нули не выдавал

declare @ii int, @ss nvarchar(maX)
set @ii=2
set @ss = 'cast((isnull(x1,'''')) as varchar(20))+'', '''
while @ii<=500

begin
select @ss=@ss+'+ cast((isnull('+'x'+cast(@ii as nvarchar)+', '''')) as varchar(20))'
select @ii=@ii+1
end
exec ('select '+ @ss +' from Test')
5 сен 14, 17:24    [16541696]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
churupaha
Member

Откуда: Краснодар
Сообщений: 1015
+ забиваем схему/данные

create table t(id int);
go

declare @cmd varchar(max) = '';

;with
l0(n) as (select 1 union all select 1),
l1(n) as (select 1 from l0 t1, l0 t2),
l2(n) as (select 1 from l1 t1, l1 t2),
l3(n) as (select 1 from l2 t1, l2 t2),
l4(n) as (select 1 from l3 t1, l3 t2),
rt(n) as (select row_number() over(order by (select 0)) from l4 t1, l4 t2)
select top(500)
	@cmd += 'alter table t add c' + cast(n as varchar(5)) + ' int default rand(checksum(newid())) * 10;'
from
	rt;

exec(@cmd);
go

alter table t drop column id;
go

alter table t rebuild;
go

insert into t default values;
go 5



+ гавнакод

select *
from
	t;
go

with t0(x) as
(
	select *
	from
		t
	for xml path('r'), type
),
t1 as
(
	select
		row_number() over(order by(select 0)) as rn,
		tmp.xn.query('/r/*') as xc
	from
		t0
			cross apply
		t0.x.nodes('/r') as tmp(xn)
)
select
	xc.query
	('
		for $x in //text()
		return concat(string($x), ":")
	')
from 
	t1
go

5 сен 14, 20:41    [16542694]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
churupaha
Member

Откуда: Краснодар
Сообщений: 1015
+ гавнакод fixed

select *
from
	t;
go

with t0(x) as
(
	select *
	from
		t
	for xml path('r'), type
)
select
	cast
	(
		tmp.xn.query
		(
			'
				for $x in ./*/text()
				return concat(string($x), ":")
			'
		) as nvarchar(max)
	) as xc
from
	t0
		cross apply
	t0.x.nodes('/r') as tmp(xn)
go

5 сен 14, 21:14    [16542838]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строку  [new]
Igorgg
Member

Откуда:
Сообщений: 83
Изменил код:

CREATE FUNCTION [dbo].[IsWriteSign](@x1 varchar,@sign varchar)
RETURNS varchar
AS
BEGIN
if (@x1 = @sign)
RETURN ''
if ((@x1 is NULL) or (len(@x1) = 0)) 
RETURN ''
return @sign
END

declare @ii int 
declare @ss varchar(MAX)
set @ii=1
set @ss = ''
declare @w int
set @w =500
while @ii<=@w

begin
if (@ii = @w)
begin
	if (@ii > 1)
	begin
		set  @ss=@ss+'+isnull('+'cast(X'+cast(@ii as nvarchar)+' as varchar),'''')'
	end
	else
	begin
		set  @ss=@ss+'isnull('+'cast(X'+cast(@ii as nvarchar)+' as varchar),'''')'
	end
	
end
else
	if (@ii = 1)
	begin
		set  @ss=@ss+'isnull('+'cast(X'+cast(@ii as nvarchar)+' as varchar),'''')+
		[dbo].[IsWriteSign](isnull('+'cast(X'+cast(@ii as nvarchar)+' as varchar),''''),'';'')'
	end
	else
	begin	
		set  @ss=@ss+'+isnull('+'cast(X'+cast(@ii as nvarchar)+' as varchar),'''')+
		[dbo].[IsWriteSign](isnull('+'cast(X'+cast(@ii as nvarchar)+' as varchar),''''),'';'')'
	end
set @ii=@ii+1
end
select('select top 1 '+ @ss +','+@ss2+' from Test')
--exec('select '+ @ss +' from Zones')

Всем спасибо

Сообщение было отредактировано: 6 сен 14, 01:05
5 сен 14, 22:26    [16543064]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить