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

Откуда:
Сообщений: 29
Всем здравствуйте!

Подскажите, может кто сталкивался. Есть в таблице SQL столбец тип varchar(40). Значение вносят номер договора и дату. Но у всех строк по разному, у кого-то просто номер и дата, где-то словом договор от и дата, где-то дата и рядом г..
Вопрос как вытянуть только дату? Понятно, что надо делать отдельное заполнение, но сейчас это срочно.

Пример

112/747 ОТ 16.11.2007
23 ОТ 17.10.2012
NULL
18/11 ОТ 13.11.2007
616 ОТ 23.12.2015                       
112 ОТ 01.09.2004
ДОГОВОР 14 ОТ 04.01.2016
35 ОТ 20.01.2014
34 ОТ 04.01.16                          
26 июл 16, 14:23    [19457118]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
o-o
Guest
Maxim696
где-то дата и рядом г..

у вас не где-то рядом г, а сплошное г.
архитектора таблицы посадить, чтоб руками и глазами теперь парсил
26 июл 16, 14:40    [19457243]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2423
Maxim696,

везде есть "ОТ" от него и пляшите:)
26 июл 16, 14:42    [19457274]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
o-o
Guest
строке сделать reverse и найти первый пробел (charindex).
досюда отрезать (substring).
реверснуть обратно.
г заменить на ''.
разношерстная, но будет дата
26 июл 16, 14:43    [19457285]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
CrazHunt
Member

Откуда:
Сообщений: 40
Вот с такой датой "04.01.16" будет проблема при конвертации в дату.
Т.е. еще надо отпарсивать знаки после последней точки (реверс -> charindex первой точки -> substring -> реверс) и добавлять "20".
Если есть договора до 2000-х, то еще ставить кейс (если год после "16", то доставлять "19", иначе "20")
Потом собирать обратно
26 июл 16, 14:52    [19457334]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
Владислав Колосов
Member

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

эта задача не для TSQL, а для языков, которые хорошо работают со строками. Тот же VBА и т.п.
26 июл 16, 15:15    [19457474]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
o-o
Guest
CrazHunt
Вот с такой датой "04.01.16" будет проблема при конвертации в дату.
Т.е. еще надо отпарсивать знаки после последней точки (реверс -> charindex первой точки -> substring -> реверс) и добавлять "20".
Если есть договора до 2000-х, то еще ставить кейс (если год после "16", то доставлять "19", иначе "20")
Потом собирать обратно

ничего не надо обратно собирать,
в том же кейсе формат нужный указать
declare @t table(g varchar(40));
insert into @t values
('112/747 ОТ 16.11.2007'),
('23 ОТ 17.10.2012'),
(NULL),
('18/11 ОТ 13.11.2007'),
('616 ОТ 23.12.2015'),                      
('112 ОТ 01.09.2004'),
('ДОГОВОР 14 ОТ 04.01.2016'),
('35 ОТ 20.01.2014'),
('34 ОТ 04.01.16'),
('34 ОТ 04.01.16Г.');

select g,
       a.dt1 as uzhe_data,
       case len(a.dt1)
            when 10 then convert (date, a.dt1, 103)
            when 8 then convert (date, a.dt1, 4)
       end as dt     
            
from @t cross apply (select ltrim(replace(replace(reverse(left(reverse(g), charindex(' ',reverse(g)))),'Г.', ''),'Г.', ''))as dt1) a;
26 июл 16, 15:19    [19457495]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
Илья_1985
Member

Откуда:
Сообщений: 7
Maxim696,
Я бы так сделал:
declare @t table(g varchar(40), [Date] date null);
insert into @t (g) values
('112/747 ОТ 16.11.2007'),
('23 ОТ 17.10.2012'),
(NULL),
('18/11 ОТ 13.11.2007'),
('616 ОТ 23.12.2015'),                      
('112 ОТ 01.09.2004'),
('ДОГОВОР 14 ОТ 04.01.2016'),
('35 ОТ 20.01.2014'),
('34 ОТ 04.01.16'),
('34 ОТ 04.01.16Г.');

update @t
	set [Date] =  try_convert (date, substring (g, patindex('%[0-9][0-9].[0-9][0-9].[0-9][0-9][0-9][0-9]%', g), 10), 104) 
where patindex('%[0-9][0-9].[0-9][0-9].[0-9][0-9][0-9][0-9]%', g) > 0 and date is null 

select * from @t  

update @t
	set [Date] =  try_convert (date, substring (g, patindex('%[0-9][0-9].[0-9][0-9].[0-9][0-9]Г%', g), 8), 4) 
where patindex('%[0-9][0-9].[0-9][0-9].[0-9][0-9]Г%', g) > 0 and date is null 

select * from @t 	

update @t
	set [Date] =  try_convert (date, substring (g, patindex('%[0-9][0-9].[0-9][0-9].[0-9][0-9]%', g), 8), 4) 
where patindex('%[0-9][0-9].[0-9][0-9].[0-9][0-9]%', g) > 0 and date is null 

select * from @t 
26 июл 16, 15:47    [19457719]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
Илья_1985
Member

Откуда:
Сообщений: 7
Сервер 2012-ый?
Если нет, то вместо try_convert нужно будет использовать convert, а внизу условие с функцией IsDate.
26 июл 16, 15:50    [19457730]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
o-o
Guest
Илья_1985,
1. чегой-то вместо одного скана 3 делать
2. кто сказал, что у него не 2008-ой сервер?
3. сперва-то еще альтер табличке сделаете, да (add column) ?
потом апдэйты и сплиты.
а если табличка в 400гиг, не пробовали такое с ней проделать?
26 июл 16, 15:55    [19457772]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
Илья_1985
Member

Откуда:
Сообщений: 7
o-o, Моё решение не является идеальным. Можете предложить лучшее. Три прохода для наглядности. Можно и coalesce использовать. создавать столбец не обязательно - можно этот функционал в функцию завернуть и вообще без столбца обойтись. а если из этого сделать скалярную функцию и в вычисляемое поле persisted закинуть, так вообще по нему можно индекс построить. Впрочем, это не важно - может, там и 2012 сервер, и табличка на пару тыс. записей - тогда и так вполне себе решение.
26 июл 16, 16:07    [19457848]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
o-o
Guest
Илья_1985
Можете предложить лучшее.

снимите противо_о-о_шные очки, мое решение выложено давно
Илья_1985
Три прохода для наглядности.

так вот и я про то же,
про наглядность.
проделайте свой тройной апдэйт на табличке в 400 Гиг.
наглядность должна проканать, словами вас не проймешь
Илья_1985
можно этот функционал в функцию завернуть

играете в Остер-2 и в задумке альтернативное издание книги вредных советов?
Илья_1985
а если из этого сделать скалярную функцию и в вычисляемое поле persisted закинуть, так вообще...

вообще ппц и будет.
вы переходите от теории к практике,
не забудьте про достойный объем тестовой таблицы.
мы вас ждем с результатами тестирования,
если вы сами свои результаты вообще дождетесь
26 июл 16, 16:16    [19457917]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
3unknown
Member

Откуда: New York
Сообщений: 140
declare @t table(g nvarchar(50));
insert into @t values
('112/747 OT 16.11.2007'),
('23 OT 17.10.2012'),
(NULL),
('18/11 OT 13.11.2007'),
('616 OT 23.12.2015'),                      
('112 OT 01.09.2004'),
('Dogovor 14 OT 04.01.2016'),
('35 OT 20.01.2014'),
('34 OT 04.01.16G'),
('34 OT 04.01.16G.');


select isnull(try_convert(date,replace(replace(substring(g,charindex('.',g)-2,len(g)-(charindex('.',g)-3)),'G.',''),'G',''),104)
,try_convert(date,replace(replace(substring(g,charindex('.',g)-2,len(g)-(charindex('.',g)-3)),'G.',''),'G',''),4)) 
from @t
26 июл 16, 16:30    [19458013]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
Илья_1985
Member

Откуда:
Сообщений: 7
o-o,
Илья_1985, у моего скрипта лишь одно приемущество - он будет работать всегда. Даже с такими, например, строками
('34 ОТ 04.01.16.'). Или с такими '34 ОТ 04.01.16. (изм)'. Скорость - аналогична вашему при умелой доработке.
26 июл 16, 16:37    [19458053]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
o-o
Guest
Илья_1985
o-o,
Илья_1985, у моего скрипта лишь одно приемущество - он будет работать всегда.

вы чего к нам двоим обращаетесь?
к себе давайте, меня не переубедите.
перестраивать таблицу, когда просят какой-то обычный селект,
такое можно себе позволить, пока у вас 10 строк или столько же гиг.
как раз ваш код положит наш сервер на уже упомянутой таблице
не говоря о том, что ваше на нашем даже не распарсится.
тоже мне, "всегда"
26 июл 16, 16:58    [19458170]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
invm
Member

Откуда: Москва
Сообщений: 9687
select
 t.[строка], m.*
from
 Таблица t cross apply
 [CLR-функция-обертка для Regex.Matches](t.[строка], '(\s|^)\d{2}\.\d{2}\.(\d{4}|\d{2})(\s|$)') m
26 июл 16, 17:25    [19458332]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
o-o
Guest
invm вместо чурюпахи!
26 июл 16, 17:29    [19458338]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
ambarka_max
Member

Откуда: Россия
Сообщений: 517
А где же случаи обработки таких данных как: "112/747 ОТ 16 сентябрября 2007". или 207 год. или 32 декабря.
2 авг 16, 11:38    [19485857]     Ответить | Цитировать Сообщить модератору
 Re: Вытащить из строки дату sql  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
ambarka_max,

а чё не указал "шистнадцятое синтября " для полноты картины?
2 авг 16, 11:40    [19485872]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить