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

A B C
Строка1 51^52 Знач1^Знач2
Строка2 53^54 Знач3^Знач4

А в результате мне нужно так


A B C
Строка1 51 Знач1
Строка1 52 Знач2
Строка2 53 Знач3
Строка2 54 Знач4

Можно ли такое сделать с помощью 1 скл запроса?
15 авг 12, 14:34    [13015135]     Ответить | Цитировать Сообщить модератору
 Re: Как программно разбить столбцы по строкам  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 3019
у Вас только по 2 значения возможны в столбцах или больше?
15 авг 12, 14:37    [13015177]     Ответить | Цитировать Сообщить модератору
 Re: Как программно разбить столбцы по строкам  [new]
Int23
Guest
Может быть и больше. Но если в В их 3 то и в С тоже 3. Например

A B C
Строка1 51^52^53 Знач1^Знач2^Знач3
15 авг 12, 14:40    [13015201]     Ответить | Цитировать Сообщить модератору
 Re: Как программно разбить столбцы по строкам  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 3019
вот почитайте Парсинг строки из таблицы
или же Разбить строку на слова
и в поиск
а там напильником допилить
15 авг 12, 14:46    [13015264]     Ответить | Цитировать Сообщить модератору
 Re: Как программно разбить столбцы по строкам  [new]
Int23
Guest
Спасибо за ссылки. Вот сделал скрипт



;with OKSO_XML
as
(
select KOD, NAME1, cast('<xml><item>'+replace(KODKV,'^','</item><item>')+'</item></xml>' as xml) as KODKV_XML
, cast('<xml><item>'+replace(NAMEKV1+NAMEKV2+NAMEKV3,'^','</item><item>')+'</item></xml>' as xml) as NAMEKV_XML
, NOMDESCR, NOMAKT, STATUS, DATA_UPD
from [Pluto].[dbo].[okso]
where KOD<>''
)

select okso1.KOD, okso1.NAME1, kod.kv.value('.','varchar(100)') as KODKV,
name.kv.value('.','varchar(100)') as NAMEKV,
okso1.NOMDESCR, okso1.NOMAKT, okso1.STATUS, okso1.DATA_UPD
from OKSO_XML okso1
cross apply okso1.KODKV_XML.nodes('xml/item') kod(kv)
cross apply okso1.NAMEKV_XML.nodes('xml/item') name(kv)


Но так как у меня 2 cross apply то у меня появляются лишние строки. Мне по сути надо выборки из cross apply соединить по прядковому номеру. Т.е. первый результат из первого cross apply должен соединится с первым рещзультатом из второго cross apply . Как такое написать?
15 авг 12, 15:23    [13015549]     Ответить | Цитировать Сообщить модератору
 Re: Как программно разбить столбцы по строкам  [new]
Int23
Guest
Вообщем сделал я так.


select okso1.KOD, okso1.NAME1, kod.kv.value('.','varchar(100)') as KODKV,
name.kv.value('.','varchar(100)') as NAMEKV,
okso1.NOMDESCR, okso1.NOMAKT, okso1.STATUS, okso1.DATA_UPD
from OKSO_XML okso1
cross apply (select 1 as Number
union all
select 2 as Number
union all
select 3 as Number
union all
select 4 as Number
union all
select 5 as Number
) p
cross apply okso1.KODKV_XML.nodes('/xml/item[position()=sql:column("Number")]') kod(kv)
cross apply okso1.NAMEKV_XML.nodes('/xml/item[position()=sql:column("Number")]') name(kv)
order by okso1.KOD, p.Number


Если можно как то сделать более красиво, то покажите пожалуйста
15 авг 12, 15:47    [13015717]     Ответить | Цитировать Сообщить модератору
 Re: Как программно разбить столбцы по строкам  [new]
qwerty112
Guest
Int23
Может быть и больше. Но если в В их 3 то и в С тоже 3. Например

A B C
Строка1 51^52^53 Знач1^Знач2^Знач3

а "больше" - насколько ?
вообщем, если там "вменяемого" порядка цифра, то проще так
громодко, конечно, но с гарантированным порядком ...
declare @t table (A varchar(10), B varchar(50), C varchar(50))

insert into @t (A, B, C)

select 'Строка1',    '51^52^53',   'Знач1^Знач2^Знач3' union all
select 'Строка2',    '53^54',      'Знач3^Знач4'
---

;with cte as
(select A, 
cast('<row><b>'+replace(B, '^', '</b><b>')+'</b>'+
'<c>'+replace(C, '^', '</c><c>')+'</c></row>' as xml) as X
from @t)

select t1.A, z.xz1, z.xz2
from cte t1
cross apply 
	(select t.y.value('(b)[1]', 'varchar(10)') as xz1, t.y.value('(c)[1]', 'varchar(10)') as xz2
	from t1.X.nodes('/row') as t(y)) z
where z.xz1 is not null and z.xz2 is not null 

union all

select t1.A, z.xz1, z.xz2
from cte t1
cross apply 
	(select t.y.value('(b)[2]', 'varchar(10)') as xz1, t.y.value('(c)[2]', 'varchar(10)') as xz2
	from t1.X.nodes('/row') as t(y)) z
where z.xz1 is not null and z.xz2 is not null 

union all

select t1.A, z.xz1, z.xz2
from cte t1
cross apply 
	(select t.y.value('(b)[3]', 'varchar(10)') as xz1, t.y.value('(c)[3]', 'varchar(10)') as xz2
	from t1.X.nodes('/row') as t(y)) z
where z.xz1 is not null and z.xz2 is not null 

order by 1, 2, 3

A          xz1        xz2
---------- ---------- ----------
Строка1    51         Знач1
Строка1    52         Знач2
Строка1    53         Знач3
Строка2    53         Знач3
Строка2    54         Знач4
15 авг 12, 15:50    [13015741]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить