Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Andrew_vb1110 Member Откуда: Симферополь Сообщений: 538 |
Есть текстовая строка: [D129x3y8] + [D127x3y9] + [D123x3y10] + [D129x3y11] + [D129x3y12] + [D129x3y13] + [D129x3y7] как распарсить строку (выделить документы) и получить следующий столбец записей (но номер D может быть от одного до 4 символов) В результате должен быть следующий набор: D123 D127 D129 |
27 апр 12, 12:43 [12479107] Ответить | Цитировать Сообщить модератору |
мимо
Guest |
declare @x as varchar (250) = '[D129x3y8] + [D127x3y9] + [D123x3y10] + [D129x3y11] + [D129x3y12] + [D129x3y13] + [D129x3y7]' declare @xml as xml = replace(replace(REPLACE(@x,'[','<b>'),']','</b>'),' + ','') select distinct left(y.value('.','varchar(100)'),4) from @xml.nodes('b') as x(y) order by 1 |
27 апр 12, 12:59 [12479217] Ответить | Цитировать Сообщить модератору |
Mnior Member Откуда: Кишинёв Сообщений: 6723 |
Причём тут SQL, это что нельзя на клиенте делать? |
27 апр 12, 13:04 [12479255] Ответить | Цитировать Сообщить модератору |
Andrew_vb1110 Member Откуда: Симферополь Сообщений: 538 |
мимо, спасибо конечно. А как то классическим SQL запросом, без использования XML можно сделать? |
27 апр 12, 13:04 [12479256] Ответить | Цитировать Сообщить модератору |
Мистер Хенки Member Откуда: канализация Сообщений: 6615 |
можно через таблицу с числами, через инлайн функцию или через XML. |
||
27 апр 12, 13:14 [12479369] Ответить | Цитировать Сообщить модератору |
Mnior Member Откуда: Кишинёв Сообщений: 6723 |
А мой пост вы игнорируете. Это нормально. |
||
27 апр 12, 13:14 [12479376] Ответить | Цитировать Сообщить модератору |
мимо
Guest |
sql - это язык. а хмл - это такой тип данных (как инт или варчар). от sql2005 и выше. А сделать можно, конечно... А использование анпивота относится к классический скл или нет? |
||
27 апр 12, 13:15 [12479382] Ответить | Цитировать Сообщить модератору |
Andrew_vb1110 Member Откуда: Симферополь Сообщений: 538 |
Да, приведите пожалуйста пример с использованием PIVOT |
||||
27 апр 12, 13:40 [12479599] Ответить | Цитировать Сообщить модератору |
Andrew_vb1110 Member Откуда: Симферополь Сообщений: 538 |
Скрипт не работает |
||
27 апр 12, 13:43 [12479606] Ответить | Цитировать Сообщить модератору |
Strangers Member [заблокирован] Откуда: Україна Сообщений: 2613 |
а так по классически? :)SELECT distinct SUBSTRING(_Str, CHARINDEX('D',_Str,Pos-5),Pos-CHARINDEX('D',_Str,Pos-5)) FROM (SELECT @x as _Str) m CROSS JOIN (SELECT a.Pos FROM (-- первая 1000 чисел select k.number*100 + k1.number*10 + k2.number Pos from master.dbo.spt_values k FULL JOIN master.dbo.spt_values k1 ON k1.type = k.type and k1.number between 0 and 9 FULL JOIN master.dbo.spt_values k2 ON k1.type = k2.type and k2.number between 0 and 9 where k.type = 'P' and k.number between 0 and 9) a WHERE a.Pos between 1 and LEN(@x) and SUBSTRING(@x,a.Pos,1) = 'x') z |
27 апр 12, 13:44 [12479613] Ответить | Цитировать Сообщить модератору |
Andrew_vb1110 Member Откуда: Симферополь Сообщений: 538 |
Strangers, Ух Ты! Вот это здорово и то что мне надо. Спасибо огромное. |
27 апр 12, 13:46 [12479632] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47047 |
C помощью таблицы чисел:DECLARE @S VARCHAR(100)='[D129x3y8] + [D127x3y9] + [D123x3y10] + [D129x3y11] + [D129x3y12] + [D129x3y13] + [D129x3y7]'; SELECT DISTINCT SUBSTRING(@S,number+1,CHARINDEX('x',@S,number+1)-number-1) FROM master.dbo.spt_values WHERE type='P' AND SUBSTRING(@S,number,1)='[' ORDER BY 1; |
27 апр 12, 13:49 [12479656] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47047 |
DECLARE @S VARCHAR(100)='[D129x3y8] + [D127x3y9] + [D123x3y10] + [D129x3y11] + [D129x3y12] + [D129x3y13] + [D129x3y7]'; SELECT DISTINCT SUBSTRING(@S,number+1,CHARINDEX('x',@S,number+1)-number-1) FROM master.dbo.spt_values WHERE type='P' AND number BETWEEN 1 AND LEN(@S) AND SUBSTRING(@S,number,1)='[' ORDER BY 1; |
||
27 апр 12, 13:52 [12479675] Ответить | Цитировать Сообщить модератору |
Andrew_vb1110 Member Откуда: Симферополь Сообщений: 538 |
У меня на самом деле переменная @S - это поле в таблице (поле Text). ID Text 126 [D129x3y8] + [D127x3y9] + [D123x3y10] + [D129x3y11] + [D129x3y12] + [D129x3y13] + [D129x3y7] Поля таблицы: ID - integer, Text - varchar(250). Мне надо перебрать по всей таблице (по полю Text). Как лучше сделать курсор перебора по всем записям таблицы. Т.е. окончательный рекордсет должен быть: ID Text 126 D123 126 D127 126 D129 126 D129 126 D129 126 D129 126 D129 |
||||
27 апр 12, 15:30 [12480502] Ответить | Цитировать Сообщить модератору |
Strangers Member [заблокирован] Откуда: Україна Сообщений: 2613 |
DECLARE @t table (ID int, [Text] varchar(250)) INSERT INTO @t SELECT 126, '[D129x3y8] + [D127x3y9] + [D123x3y10] + [D129x3y11] + [D129x3y12] + [D129x3y13] + [D129x3y7]' UNION SELECT 127, '[D129x3y8] + [D127x3y9] + [D129x3y11] + [D129x3y12]' SELECT DISTINCT ID, SUBSTRING([Text],number+1,CHARINDEX('x',[Text],number+1)-number-1) FROM master.dbo.spt_values CROSS JOIN @t WHERE type='P' AND number BETWEEN 1 AND LEN([Text]) AND SUBSTRING([Text],number,1)='[' ORDER BY 1; |
27 апр 12, 15:54 [12480683] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47047 |
Пары миллионов записей должно хватить. Использовать там, где у меня master.dbo.spt_values. 2. Трудно обобщить на поля таблицы? ![]() SELECT DISTINCT T.ID, SUBSTRING(T.[Text],V.number+1,CHARINDEX('x',T.[Text],V.number+1)-V.number-1)[Text] FROM [Table] T JOIN master.dbo.spt_values V ON V.type='P' AND V.number BETWEEN 1 AND LEN(T.[Text]) AND SUBSTRING(T.[Text],V.number,1)='[' ORDER BY 1,2; |
||||
27 апр 12, 16:02 [12480781] Ответить | Цитировать Сообщить модератору |
Mnior Member Откуда: Кишинёв Сообщений: 6723 |
Столько гемора ради парсирования строк на стороне сервера. Один раз привести данные в реляционный стандартный формат и забыть как страшный сон. А так генерить-парсить туда-сюда по 100 раз за раз. Зачем? Ответ: человек любит приключения на свою *опу. |
27 апр 12, 22:49 [12482528] Ответить | Цитировать Сообщить модератору |
Andrew_vb1110 Member Откуда: Симферополь Сообщений: 538 |
Спасибо - работает. Но я так понимаю, что ограничение идет на spt_values на 2048 |
||||
28 апр 12, 09:16 [12483486] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47047 |
можно spt_values скроссджойнить с собой, можно взять другую таблицу побольше, пронумеровать строки ROW_NUMBER()ом. Но всё это не очень хорошо. Например, есть проблема доступа обычных пользователей к базе master и spt_values и т.п. Своя специальная таблмца лишена этих недостатков, её можно проиндексировать и т.д. |
||||
28 апр 12, 09:26 [12483520] Ответить | Цитировать Сообщить модератору |
Между сообщениями интервал более 1 года. |
stells2 Member Откуда: Оклахома Пригород Колымы Сообщений: 898 |
* что бы не создавать нового** Добрый день. Столкнулся с вопросом который в других системах как-то легко решается а тут приходится что-то городить и чем дальше тем глубже :) Суть: Есть возможный набор строк
из этого должно возвращаться
т.е. должно быть число от 1 до 9999 (4 знака) 1. убираться ведущие нули 2. отсекаться тире и все что за ним интересно: 002 = 2 020 = 20 00008 = 8 000080 = 80 в похожем по организации SQL - InfoPlus это реализовано может быть, например так: SUBSTRING(TRIM(SUBSTRING(1 OF trim(LEADING '0' from FUSNNUM) BETWEEN '-')) FROM 1 FOR 4) где FUSNUM это поле с данными. в Orcale за счет регулярных выражений. А тут ничего умного не приходит в голову кроме DECLARE @s varchar(25); SET @s = '00900-8'; SELECT CAST(SUBSTRING(REPLACE(SUBSTRING(@s, 1, CASE WHEN CHARINDEX('-',@s)<=0 THEN LEN(@s) ELSE CHARINDEX('-',@s) end),'-',''),1,4) as INT) но результат не верен 90 а правильно 900 |
||||||||||||||||||||||||||||||
24 июн 14, 10:04 [16210164] Ответить | Цитировать Сообщить модератору |
Minamoto Member Откуда: Москва Сообщений: 1162 |
stells2, я бы сделал так:select cast(case when CHARINDEX('-', @s) > 0 then substring(@s, 1, charindex('-', @s)-1) else @s end as int) |
24 июн 14, 10:12 [16210210] Ответить | Цитировать Сообщить модератору |
Minamoto Member Откуда: Москва Сообщений: 1162 |
stells2, ой, забыл обрезку. Вот пример сразу с данными: select cast(left(case when CHARINDEX('-', t1) > 0 then substring(t1, 1, charindex('-', t1)-1) else t1 end, 4) as int) from (values ('5695'), ('00326-3'), ('03264'), ('000100-2'), ('02303'), ('003282'), ('3441-1'), ('3441-2'), ('14650'), ('2534-2'), ('2534-1'), ('25340-5'), ('01-5'), ('010-4')) as t (t1) И, да, лучше уж новую тему завести под такой вопрос. |
24 июн 14, 10:18 [16210231] Ответить | Цитировать Сообщить модератору |
stells2 Member Откуда: Оклахома Пригород Колымы Сообщений: 898 |
да, открыл.. Распарсить строку в 4-х значное число там и ответил. |
||
24 июн 14, 10:42 [16210391] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |