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

Откуда:
Сообщений: 276
Есть таблица называется Brak. В ней есть поле Letter_Date тип varchar(50) по идее в нем должна хранится дата. Фактически же там присутствуют записи как с датой так и просто текст такого вида например: "192/65 от 19.12.05".

Мне же нужно отобрать из этой таблицы записи где Letter_Date>='01.01.2008' и Letter_Date<='31.12.2008'

Пишу так:

select * from

(select * from where isdate(Letter_Date)=1) AS t

where cast ('2008/01/01' AS datetime)<=t.Letter_Date

получаю ошибку:

Syntax error converting datetime from character string.
30 июл 09, 09:03    [7476721]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
lazovik
Member

Откуда:
Сообщений: 269
4Q,

Ну дык и бери 8 символов с права!
30 июл 09, 09:08    [7476744]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
4Q
Member

Откуда:
Сообщений: 276
Непрокатит. Там может быть дата в любом месте строки. Может быть вообще без даты просто текст.
30 июл 09, 09:10    [7476747]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74927
4Q
Может быть вообще без даты просто текст.


Это пять!!! Почему бы там не навести порядок и тип данных поля сделать datetime?!
30 июл 09, 09:14    [7476763]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
4Q
Member

Откуда:
Сообщений: 276
Это обязательно, но позже. Но мне уже просто интересно, можно ли с этой таблицей работать так как есть.
30 июл 09, 09:24    [7476803]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
vino
Member

Откуда:
Сообщений: 1191
4Q
Есть таблица называется Brak. В ней есть поле Letter_Date тип varchar(50) по идее в нем должна хранится дата. Фактически же там присутствуют записи как с датой так и просто текст такого вида например: "192/65 от 19.12.05".

Мне же нужно отобрать из этой таблицы записи где Letter_Date>='01.01.2008' и Letter_Date<='31.12.2008'

Пишу так:

select * from

(select * from where isdate(Letter_Date)=1) AS t

where cast ('2008/01/01' AS datetime)<=t.Letter_Date

получаю ошибку:

Syntax error converting datetime from character string.
вот проблемный cast
30 июл 09, 09:37    [7476870]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
vino
Member

Откуда:
Сообщений: 1191
4Q, может, так
select * from 

(select * from where isdate(Letter_Date)=1) AS t 

where '20080101'<=cast (t.Letter_Date AS datetime)
30 июл 09, 09:38    [7476875]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74927
4Q
Это обязательно, но позже. Но мне уже просто интересно, можно ли с этой таблицей работать так как есть.


Путью - нет.
30 июл 09, 09:39    [7476883]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
vino
Member

Откуда:
Сообщений: 1191
4Q, а полностью можно и так
select * from 

(select * from where isdate(Letter_Date)=1) AS t 

where cast (t.Letter_Date AS datetime) between '20080101' and '20081231 23:59:59.997'
[/quot]
30 июл 09, 09:40    [7476886]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
vino
Member

Откуда:
Сообщений: 1191
4Q
Есть таблица называется Brak...

логично
30 июл 09, 09:41    [7476894]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
4Q
Member

Откуда:
Сообщений: 276
vino
4Q, может, так
select * from 

(select * from where isdate(Letter_Date)=1) AS t 

where '20080101'<=cast (t.Letter_Date AS datetime)


Syntax error converting datetime from character string.
30 июл 09, 09:42    [7476897]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
vino
4Q, а полностью можно и так
select * from 

(select * from where isdate(Letter_Date)=1) AS t 

where cast (t.Letter_Date AS datetime) between '20080101' and '20081231 23:59:59.997'
[/quot]Проблема ещё и в том, что CAST и ISDATE работают с текущими установками LANGUAGE и DATEFORMAT.
А в каком формате даты были записаны в строки, мы не знаем.
В общем, если автор точно скажет, какого вида фрагмент с датой должен быть в строке, задача решается тривиально.
Если же формат может быть разным, то задача в полном объёме нерешаема
(точнее, можно, конечно, перебрать все строки вручную).
30 июл 09, 09:53    [7476974]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
4Q
Member

Откуда:
Сообщений: 276
iap
vino
4Q, а полностью можно и так
select * from 

(select * from where isdate(Letter_Date)=1) AS t 

where cast (t.Letter_Date AS datetime) between '20080101' and '20081231 23:59:59.997'
Проблема ещё и в том, что CAST и ISDATE работают с текущими установками LANGUAGE и DATEFORMAT.
А в каком формате даты были записаны в строки, мы не знаем.
В общем, если автор точно скажет, какого вида фрагмент с датой должен быть в строке, задача решается тривиально.
Если же формат может быть разным, то задача в полном объёме нерешаема
(точнее, можно, конечно, перебрать все строки вручную).[/quot]

15.10.1999 - вот такого вида.
30 июл 09, 10:03    [7477046]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
24Q
если Вам интересно, тогда предлагаю посмотреть функции convert и строковые. и экспериментировать уже на данных, видя их.

для спящего время бодрствования равносильно сну
30 июл 09, 11:17    [7477668]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
Glory
Member

Откуда:
Сообщений: 104760
4Q


15.10.1999 - вот такого вида.


А 01.02.1999 - это будет 1е февраля или 2е января ?
30 июл 09, 11:21    [7477709]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
vino
Member

Откуда:
Сообщений: 1191
4Q
15.10.1999 - вот такого вида.
можно попробовать перебрать допустимые варианты
set DATEFORMAT dmy;
select * from Brak where CASE IsDate(Letter_Date) WHEN 1 THEN
	(CASE len(Letter_Date) WHEN 8 THEN
		CASE WHEN charindex('/',Letter_Date) > 0 THEN convert(datetime, Letter_Date, 3)
			WHEN charindex('.',Letter_Date) > 0 THEN convert(datetime, Letter_Date, 4)
			WHEN charindex('-',Letter_Date) > 0 THEN convert(datetime, Letter_Date, 5)
			ELSE 0 END --ELSE cast(Letter_Date as datetime)
		WHEN 10 THEN
		CASE WHEN charindex('/',Letter_Date) > 0 THEN convert(datetime, Letter_Date, 103)
			WHEN charindex('.',Letter_Date) > 0 THEN convert(datetime, Letter_Date, 104)
			WHEN charindex('-',Letter_Date) > 0 THEN convert(datetime, Letter_Date, 105)
			ELSE 0 END --ELSE cast(Letter_Date as datetime)
	ELSE 0 END
 ELSE 0 END
 between '20080101' and '20081231 23:59:59.997')
но нужно еще учитывать параметр деления столетий из-за имеющихся дат.
Вообще-то для нормального использования добавьте в таблицу поле типа datetime и обновите его из Letter_Date, а потом вручную исправьте данные в оставшихся записях - так легче будет дальше работать. А еще старую работающую систему можно модернизировать триггером, который будет обновлять новое поле, а если не корректно задана дата, - отменит транзакцию
30 июл 09, 12:03    [7478122]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
4Q
Member

Откуда:
Сообщений: 276
Glory
4Q


15.10.1999 - вот такого вида.


А 01.02.1999 - это будет 1е февраля или 2е января ?


А это от формата зависит. dmy или mdy
3 авг 09, 11:18    [7489887]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
Glory
Member

Откуда:
Сообщений: 104760
4Q
Glory
4Q


15.10.1999 - вот такого вида.


А 01.02.1999 - это будет 1е февраля или 2е января ?


А это от формата зависит. dmy или mdy

А разве не от того, кто вносил эти данные в поле ? Как вы узнаете, какую дату имел ввиду пользователь ?
3 авг 09, 11:24    [7489929]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
4Q
Member

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

а ну это просто. пользователь имел ввиду dmy.
4 авг 09, 09:23    [7493568]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
Anddros
Member

Откуда:
Сообщений: 1077
declare @t table (id int identity, letter_date varchar(50))
insert @t select '15.10.2008'
union all select '15.15.2008'
union all select ' sadfas 4.10.2008 wef'
union all select 'N 11 от 16.10.2008 рпорп'
union all select '17.10.2008 хххх'
union all select 'dfbgdsf 17/10/2008 хххх'
union all select ' sdfg 17-10-2008 хххх'
union all select ' sdfg 17-10-2006 хххх'
union all select '15.10.2009'
union all select 'N 11 от 16.10.2007 рпорп'
union all select '17.10.2006 хххх'
union all select '11.10 '
union all select '11.10-4.05.2008'
union all select '11.10-04.05.2008'

set dateformat dmy

select id, letter_date--,p1,p2,d,dd
from @t
cross apply (select patindex('%[0-3][0-9][./-][01][0-9][./-][0-9][0-9][0-9][0-9]%',letter_date) p1,
patindex('%[0-9][./-][01][0-9][./-][0-9][0-9][0-9][0-9]%',letter_date) p2)t1
cross apply (select replace(replace(substring(letter_date,
	case when p1>0 then p1 when p2>0 then p2 else 1 end, 
	case when p1>0 then 10 when p2>0 then 9 else 0 end),'-','.'),'/','.') d)t2
cross apply (select case when isdate(d)=1 then convert(datetime,d,104) else null end dd)t3
where dd>='20080101' and dd<'20090101'
4 авг 09, 11:44    [7494568]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
4Q,

поскольку внятного описания возможных форматов строки нет, где в ней может находиться дата
и в каком формате - пока неизвестно, то я предположил, что:
1. строковое представление даты может быть в любом месте строки
2. оно должно без ошибок преобразовываться в DATETIME при SET LANGUAGE 'русский' и SET DATEFORMAT dmy (ISDATE для этого представления =1)
Тогда
USE tempdb;
SET NOCOUNT ON;
IF OBJECT_ID(N'T','U')IS NOT NULL DROP TABLE T;
GO
CREATE TABLE T(id int identity, s varchar(50));
INSERT T(s)
          SELECT '192/65 от 19.12.05'
UNION ALL SELECT 'ggg56/fr43w7 от 01/12/1997 лдгмпа'
UNION ALL SELECT 'ibtfr от 01/12.1997 7777'
UNION ALL SELECT 'ibtfr от bjtrdehutrhuytrsdu'
UNION ALL SELECT 'furi76rbg авг  4 2009 ionuhuip';

DECLARE @From DATETIME, @To DATETIME;
SELECT @From='19970203', @To='19971215';

SET LANGUAGE русский;
SELECT * FROM T;

SELECT DISTINCT T.id, T.s
FROM T
JOIN master.dbo.spt_values V ON V.type='P' AND V.number BETWEEN 1 AND LEN(T.s)
JOIN master.dbo.spt_values VV ON VV.type='P' AND V.number BETWEEN 1 AND LEN(T.s)-V.number
WHERE CASE ISDATE(SUBSTRING(T.s,VV.number,V.number)) WHEN 1 THEN CAST(SUBSTRING(T.s,VV.number,V.number)AS DATETIME)END BETWEEN @From AND @To;

IF OBJECT_ID(N'T','U')IS NOT NULL DROP TABLE T;
Только надо учесть, что некоторые строки попадут в выборку,
потому что многие форматы строкового представления даты - это просто последовательность цифр.
Например, '7777' - это легальная дата (1 января 7777 года)
4 авг 09, 12:20    [7494922]     Ответить | Цитировать Сообщить модератору
 Re: Не получается запрос  [new]
4Q
Member

Откуда:
Сообщений: 276
Всем, спасибо. все получилось.
5 авг 09, 13:32    [7500398]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить