Получить дату из подстроки, где предложение SQL выбрать * EDITED * - PullRequest
1 голос
/ 22 декабря 2011

У меня есть дата, хранящаяся в текстовом поле с другим текстом.Почему они просто не поместили это в поле даты?Я понятия не имею, но у меня нет возможности изменить это сейчас.В другом месте кода я делаю это, чтобы получить записи, где эта дата находится в определенном диапазоне.Работает нормально.

For Each i As InventoryItem In inventoryList
  index = i.Notes.IndexOf("on {") + 4
  scanned_dt = i.Notes.Substring(index, i.Notes.Length - index - 1)
  If Date.Parse(scanned_dt) >= startDate And Date.Parse(scanned_dt) <= endDate Then
    ...

Я сейчас пытаюсь получить общее количество предметов за определенный диапазон дат.Это заявление sql работает, чтобы получить сумму за все даты.Как я могу обновить предложение Where, чтобы считать только те элементы, в которых i.Notes содержит дату от startDate до endDate

Dim sql As String = "Select COUNT(inv_PartNum) from lester.inventory i join lester.vendor v on v.vendor_ID = i.vendor_ID Where v.vendor_Name = '" + vendorName + "' AND i.inv_Desc LIKE '%" + size + "%'"

* EDITED * Я пришел с этим оператором выбора sql:

SELECT COUNT(i.inv_PartNum) FROM cdms.lester.inventory AS I
join CDMS.lester.vendor AS v on v.vendor_ID = i.vendor_ID Where v.vendor_Name = 'JVE-285' 
AND CONVERT(DATETIME,
SUBSTRING(i.inv_Notes, CharIndex('on {', i.inv_Notes)+4, len(i.inv_Notes)-(CharIndex('on {', i.inv_Notes) + 4)
),101) BETWEEN '01-01-2011' AND '04-04-2011'

Но я получаю эту ошибку: Преобразование типа данных char в тип данных datetime привело к выходу за пределы диапазона datetimeзначение.

Пытаясь понять это, я создал следующий оператор sql select:

SELECT * FROM (
SELECT i.inv_Notes, 
CONVERT(DATETIME,SUBSTRING(i.inv_Notes, CharIndex('on {',i.inv_Notes)+4,LEN(i.inv_Notes)-(CharIndex('on {', i.inv_Notes) + 4)),101) AS d
FROM cdms.lester.inventory AS i
join CDMS.lester.vendor AS v ON v.vendor_ID = i.vendor_ID WHERE v.vendor_Name = 'JVE-285') AS s

Мой столбец inv_Notes содержит строку типа "Назначено для трейлера инструментов {JVE-285"} on {4/8/2011} "

Когда я запускаю запрос, как показано выше, я получаю свой столбец inv_Notes вместе со столбцом даты.Все даты отображаются в этом формате «2011-04-08 00: 00: 00.000», и никаких ошибок не возникает.

Однако, как только я добавляю предложение WHERE, я получаю сообщение об ошибке: преобразование типа данных char в тип данных datetime привело к значению datetime вне диапазона.

Я пытался форматировать дату в любом случае, но всегда получаю ошибку ...

WHERE s.d > CONVERT(DATETIME, '2011-1-1', 101)

WHERE s.d < GetDate()

WHERE s.d > '20110101'

WHERE s.d >= '2011-01-01'

WHERE s.d >= '01-01-2011'

WHERE s.d > '01/01/2011'

РЕДАКТИРОВАТЬ Я также пытался WHERE s.d IS NOT NULL и получаю ту же ошибку.Это, очевидно, не работает так, как я думаю, это работает б / у в точке ГДЕ, преобразование должно было уже успешно произойти.

РЕШЕНИЕ Получил эту работу

SELECT * FROM (
SELECT i.inv_Notes,
SUBSTRING(i.inv_Notes, CharIndex('} on {',i.inv_Notes)+6,LEN(i.inv_Notes)-(CharIndex('} on {', i.inv_Notes) + 6))
AS d
FROM cdms.lester.inventory AS i
join CDMS.lester.vendor AS v ON v.vendor_ID = i.vendor_ID WHERE v.vendor_Name = 'JVE-285') AS s
WHERE PARSENAME(REPLACE(s.d, '/', '.'), 1)+
RIGHT('00'+PARSENAME(REPLACE(s.d, '/', '.'), 3),2)+
RIGHT('00'+PARSENAME(REPLACE(s.d, '/', '.'),2),2) BETWEEN '20110407' AND '20110409'

Я пытался привести это к int и сделать целочисленное сравнение, но затем я получаю ошибку.Выяснилось, что проблема заключалась в том, что некоторые из полей inv_Notes содержат данные, такие как "Item Added {3/11/2011}". Ни одно из них не соответствует условиям для внутреннего выбора, поэтому, на мой взгляд, если он не выбран во внутреннем выборе,это не должно быть проблемой для условия внешнего выбора.Однако он пытался привести 2011 {311 к int и выдавал ошибку.Я уверен, что он пытался применить это на сегодняшний день, и поэтому у меня были предыдущие проблемы.

Ответы [ 3 ]

1 голос
/ 23 декабря 2011

Попробуйте добавить что-то похожее на это предложение WHERE в ваше утверждение:

WHERE CAST(SUBSTRING(Notes, CHARINDEX(Notes, 'on {') + 4, Length?) AS Date) BETWEEN StartDate And EndDate

Идея заключалась в том, что вы извлекаете соответствующую часть строки, комбинируя методы SubString и CharIndex, а затем преобразовываете это выражение в формат даты, чтобы его можно было использовать с оператором Between.

Best of Luck

Часть 2 Обновление:

Поскольку вы смогли выбрать дату, но не использовали ее в предложении where, я предлагаю использовать ее как оператор выбора, а затем обернуть ее в другой оператор, например:

SELECT *
FROM
(SELECT CAST(SUBSTRING(Notes, CHARINDEX(Notes, 'on {') + 4, Length?) AS Date) AS dtmNotes)
WHERE dtmNotes BETWEEN Start And End

Это просто для иллюстрации, но включает в себя весь ваш первый оператор выбора в обертке.

1 голос
/ 22 декабря 2011

Попробуйте посмотреть этот пост. Это говорит о извлечении даты из строкового поля. Это должно помочь вам написать ваш выбор:

SQL: извлечение даты из строки

0 голосов
/ 23 декабря 2011

Попробуйте это ...

при условии, что таблица со встроенной датой называется InventoryList , а столбец называется inv_Notes


SELECT *
FROM InventoryList i
WHERE

CAST(
substring(
i.inv_Notes,
patindex('%on {%',i.inv_Notes)  +4,
patindex('%[0-9][0-9][0-9][0-9]}%',i.inv_Notes)-patindex('%on {%',i.inv_Notes)
) as Datetime)

BETWEEN '12/1/2011' AND '12/23/2011

РЕДАКТИРОВАТЬ: более строгий поиск шаблона "9/9999}"


SELECT *
FROM InventoryList i
WHERE

CAST(
substring(
i.inv_Notes,
patindex('%on {%',i.inv_Notes)  +4,
patindex('%[0-9]/[0-9][0-9][0-9][0-9]}%',i.inv_Notes)-patindex('%on {%',i.inv_Notes)
) as Datetime)

BETWEEN '12/1/2011' AND '12/23/2011
...