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

Откуда:
Сообщений: 521
День добрый, торможу с утра :( Помогите плз решить задачу:
Дана таблица:
create table #t(a nvarchar(100),b nvarchar (100))
insert into #t
select ',11,139,25,','a~b~c' union
select ',139,','5' union
select ',125,356,456,139,25,','ss~~fff~ppp~uuu' union
select ',139,25,','~hjh' union
select ',17,139,25,','~jjj~ppp' 


ab
,11,139,25,a~hhh~c
,125,356,456,139,25,ss~~fff~ppp~uuu
,139,5
,139,25,~hjh
,17,139,25,~jjj~ppp


нужно получить значение из b позиции 139 в a, например в перой строке 139 находится на втором месте, значит нужно показать второе значение из b, т.е. hhh
во второй строке 139 находится на четвертом месте, значит нужно показать ppp.
в третей строке 5
в четвертой NULL
в пятой jjj

известно, что ,139, может быть только один раз в колонке a

Спасибо огромное!
11 фев 13, 13:02    [13908082]     Ответить | Цитировать Сообщить модератору
 Re: Помогите со стрингом плз  [new]
ROLpogo
Member

Откуда: Реутов
Сообщений: 219
По какому алгоритму определяется позиция текста в столбце b?
11 фев 13, 13:27    [13908303]     Ответить | Цитировать Сообщить модератору
 Re: Помогите со стрингом плз  [new]
abrashka
Member

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

в а- по запятым, значене/я всегда начинаются и заканчиваются запятыми
в б- по тильдам. Если значение в б начинается с тильды- то первое значение - NULL, т.е. тильда только разделитель
11 фев 13, 13:32    [13908351]     Ответить | Цитировать Сообщить модератору
 Re: Помогите со стрингом плз  [new]
Гость333
Member

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

set nocount on;
create table #numbers(n int identity primary key);
begin transaction;
go
insert #numbers default values;
go 10000
commit transaction;
go

create table #t(a nvarchar(100),b nvarchar (100));

insert into #t
select ',11,139,25,','a~hhh~c' union
select ',139,','5' union
select ',125,356,456,139,25,','ss~~fff~ppp~uuu' union
select ',139,25,','~hjh' union
select ',17,139,25,','~jjj~ppp';

with cte as
(
    select t.a, t.b,
           len(left(t.a, charindex(',139,', t.a))) - len(replace(left(t.a, charindex(',139,', t.a)), ',', '')) as position_a,
           nullif(substring('~' + t.b + '~', n.n + 1, charindex('~', '~' + t.b + '~', n.n + 1) - n.n - 1), '') as string,
           row_number() over(partition by t.a, t.b order by n.n) as position_b
    from #t t
         inner join #numbers n on n.n < len('~' + t.b + '~') and substring('~' + t.b + '~', n.n, 1) = '~'
)
select a, b, string
from cte
where position_a = position_b;
go

drop table #t;
drop table #numbers;
go


Тут используется временная таблица #numbers, но по идее она должна быть постоянной (т.н. "таблица чисел").
11 фев 13, 13:34    [13908366]     Ответить | Цитировать Сообщить модератору
 Re: Помогите со стрингом плз  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
abrashka
ROLpogo,

в а- по запятым, значене/я всегда начинаются и заканчиваются запятыми
в б- по тильдам. Если значение в б начинается с тильды- то первое значение - NULL, т.е. тильда только разделитель
А две тильды подряд?
11 фев 13, 13:34    [13908374]     Ответить | Цитировать Сообщить модератору
 Re: Помогите со стрингом плз  [new]
abrashka
Member

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

значит между ними NULL
11 фев 13, 13:38    [13908416]     Ответить | Цитировать Сообщить модератору
 Re: Помогите со стрингом плз  [new]
abrashka
Member

Откуда:
Сообщений: 521
Гость333,

Спасибо большое!
На тестовой таблице все сходится, но на практике не получается :(

На самом деле существует еще поле C с датой, могут быть одинаковые значения в a, но с разными датами и с разными значениями в поле b, каждую такую строку нужно обрабатывать отдельно. Вот исправленная тестовая таблица:
create table #t(a nvarchar(100),b nvarchar (100), c datetime);
insert into #t
select '17,139,10154,','~1~False','2013-01-02 11:11:15.000' union
select '17,139,10154,','~1~False','2013-01-02 09:41:34.000' union
select '17,139,10154,','~1~False','2013-01-02 07:32:53.000' union
select '17,139,10154,','~7~False','2013-01-01 19:51:17.000' union
select '17,139,10154,','~1~False','2013-01-01 18:51:37.000' union
select '17,139,10154,','~1~False','2013-01-01 17:40:05.000' union
select '17,139,10154,','~1~False','2013-01-01 16:33:16.000' union
select '17,139,10154,','kkk~1~False','2013-01-01 14:44:02.000' union
select '17,139,10154,','hjk~7~False','2013-01-01 13:44:16.000';


Результат Вашего скрипта:
abstring
17,139,10154,~1~FalseNULL
17,139,10154,~7~FalseNULL
17,139,10154,hjk~7~Falsehjk
17,139,10154,kkk~1~Falsekkk


Хотя нужно получить все 9 строк и в случае, как в первой строке- результат должен быть 1, а не NULL

Спасибо!
11 фев 13, 15:13    [13909210]     Ответить | Цитировать Сообщить модератору
 Re: Помогите со стрингом плз  [new]
Гость333
Member

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

Я что-то не пойму, в первом посте строки в столбце "a" начинаются с запятой, а сейчас уже начинаются с цифры. Вы определитесь, как должно быть.
11 фев 13, 15:30    [13909346]     Ответить | Цитировать Сообщить модератору
 Re: Помогите со стрингом плз  [new]
abrashka
Member

Откуда:
Сообщений: 521
Гость333,

сорри, во втором примере тоже должна быть запятая:
select ',17,139,10154,','~1~False','2013-01-02 11:11:15.000' union
select ',17,139,10154,','~1~False','2013-01-02 09:41:34.000' union
select ',17,139,10154,','~1~False','2013-01-02 07:32:53.000' union
select ',17,139,10154,','~7~False','2013-01-01 19:51:17.000' union
select ',17,139,10154,','~1~False','2013-01-01 18:51:37.000' union
select ',17,139,10154,','~1~False','2013-01-01 17:40:05.000' union
select ',17,139,10154,','~1~False','2013-01-01 16:33:16.000' union
select ',17,139,10154,','kkk~1~False','2013-01-01 14:44:02.000' union
select ',17,139,10154,','hjk~7~False','2013-01-01 13:44:16.000';
11 фев 13, 15:33    [13909366]     Ответить | Цитировать Сообщить модератору
 Re: Помогите со стрингом плз  [new]
Гость333
Member

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

Изменения в запросе минимальны:
set nocount on;
-- Вообще эта таблица должна быть постоянной
create table #numbers(n int identity primary key);
begin transaction;
go
insert #numbers default values;
go 10000
commit transaction;
go

create table #t(a nvarchar(100),b nvarchar (100), c datetime);

insert into #t
select '17,139,10154,','~1~False','2013-01-02 11:11:15.000' union
select '17,139,10154,','~1~False','2013-01-02 09:41:34.000' union
select '17,139,10154,','~1~False','2013-01-02 07:32:53.000' union
select '17,139,10154,','~7~False','2013-01-01 19:51:17.000' union
select '17,139,10154,','~1~False','2013-01-01 18:51:37.000' union
select '17,139,10154,','~1~False','2013-01-01 17:40:05.000' union
select '17,139,10154,','~1~False','2013-01-01 16:33:16.000' union
select '17,139,10154,','kkk~1~False','2013-01-01 14:44:02.000' union
select '17,139,10154,','hjk~7~False','2013-01-01 13:44:16.000';

with cte as
(
    select t.a, t.b, t.c,
           len(left(t.a, charindex(',139,', t.a))) - len(replace(left(t.a, charindex(',139,', t.a)), ',', '')) as position_a,
           nullif(substring('~' + t.b + '~', n.n + 1, charindex('~', '~' + t.b + '~', n.n + 1) - n.n - 1), '') as string,
           row_number() over(partition by t.a, t.b, t.c order by n.n) as position_b
    from #t t
         inner join #numbers n on n.n < len('~' + t.b + '~') and substring('~' + t.b + '~', n.n, 1) = '~'
)
select a, b, c, string
from cte
where position_a = position_b;
go

drop table #t;
drop table #numbers;
go
11 фев 13, 15:38    [13909392]     Ответить | Цитировать Сообщить модератору
 Re: Помогите со стрингом плз  [new]
abrashka
Member

Откуда:
Сообщений: 521
Гость333,

Огромное спасибо!
Куда только не пытался вставить поле даты... и к position его привязывал, и туда, и сюда...
Но не поставил поле даты перед order by n.n :(

Еще раз большое спасибо, очень помогли!
11 фев 13, 15:47    [13909463]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить