2014-01-19 2 views
0

Мне нужно создать юбилейный отчет. Это оригинальный код;sql date diff в годах - столбец varchar может быть пустым или нулевым

SELECT cs.id AS csid , 
     csi.Search_Number AS searchID , 
     csi.date_of_placement AS datePlaced , 
     ui.firstname , 
     ui.lastname , 
     cp.name AS companyname , 
     cp.address_line_1 , 
     cp.address_line_2 , 
     cp.city , 
     cp.state , 
     cp.zip , 
     cp2.name AS currentcompanyname , 
     cp2.address_line_1 AS current_address_line_1 , 
     cp2.address_line_2 AS current_address_line_2 , 
     cp2.city AS current_city , 
     cp2.state AS current_state , 
     cp2.zip AS current_zip 
FROM client_searches_individuals AS csi 
     LEFT JOIN users_info AS ui ON ui.id = csi.individual_number 
     LEFT JOIN client_searches AS cs ON cs.id = csi.search_number 
     LEFT JOIN companies AS Cp ON cp.id = cs.company_number 
     LEFT JOIN companies AS cp2 ON cp2.id = ui.current_company_number 
WHERE 0 = 0 
      <!--- This is for the varchar date field, take away anything with the year selected ---> 
       and csi.date_of_placement not like '#dateformat(attributes.startdate,'yyyy')#%' 

      <cfif attributes.startdate neq ""> 
       and right(csi.date_of_placement,5) >= '#dateformat(attributes.startdate,'mm/dd')#' 
      </cfif> 
      <cfif attributes.enddate neq ""> 
       and right(csi.date_of_placement,5) <= '#dateformat(attributes.enddate,'mm/dd')#' 
      </cfif> 
     AND ISNULL(cs.id, 0) > 0 
ORDER BY date_of_placement 

Это бедный код, потому что работает как от 2013/12/31 даст мне юбилеи в течение многих лет не = 2013 и включает в себя строки из 2014.

Я попытался с помощью DATEDIFF, но я получаю неверные ошибки даты для нулевого или пустого столбца date_of_placement (varchar).

Все, что мне действительно нужно - это любая запись, в которой есть дата размещения старше одного года на основе сегодняшней даты.

Использование следующего кода;

WHERE 0 = 0 
     AND (DATEDIFF(year, CAST(csi.date_of_placement AS DATETIME), GETDATE())) >= 1 
     AND ISNULL(cs.id, 0) > 0 
     AND ISNULL(date_of_placement, '') > '' 

Я получаю;

Msg 242, уровень 16, состояние 3, строка 2
превращение символьного типа данных в тип данных даты и времени привело к значению даты и времени вне-диапазона.

  • SQL Server 2005
  • CF 9

Я сделал запрос, чтобы исправить date_of_placement. Затем второй запрос или первый запрос, чтобы выбрать что-либо год или старше.

SELECT * 
FROM placedIndGoodDates 
WHERE 0 = 0 
     AND DATEDIFF(year, datePlaced, '#asofdate#') >= 1 
ORDER BY date_of_placement 

Запрос запросов ошибка синтаксиса.

Обнаружен «DATEDIFF (год Некорректное условное выражение, ожидаемый один из [как | нулевому | между | | в сравнении.]. Состояние,

Я что-то не хватает fundemental

+1

Почему даты хранятся как 'varchar'? Значения даты должны храниться * как даты *, а не строки. Это устаревшее приложение? – Leigh

ответ

2

Рассмотрим делать к югу выберите отформатировать date_of_placement как DATETIME, и выяснить, что вы хотите делать с записями, где date_of_placement является нулевым или пустым.

вы можете исключить те строки, используя ИНЕКЕ, или дать им некоторую произвольную дату в будущем, в зависимости от ваших потребностей.

Как только это будет сделано, вы можете использовать сравнение диапазонов дат без проблем, вместо того, чтобы вручную сравнивать с годом и т. Д. И сталкиваться с проблемами границ.

UPDATE:

На основе дополнительной информации, используйте ИНЕКЕ, чтобы удалить неверные записи перед подачей этих значений в DATEDIFF, например,

SELECT 
    CSI.OriginalDate, 
    DATEDIFF(year, CSI.OriginalDate, GETDATE()) AS YearBoundariesCrossed, 
    DATEDIFF(month, CSI.OriginalDate, GETDATE())/12 AS KindaFullYearsDifference 
FROM (
    -- sub-select to remove invalid dates and convert to date 
    SELECT 
     CAST(date_of_placement AS datetime) AS OriginalDate, 
     -- specify just the fields you need, or use the lazy * 
     * 
    FROM client_searches_individuals 
    -- use whatever check(s) you need here, I like to check for LEN() > 0 
    -- NULL entries fail this test too, which is good 
    WHERE LEN(date_of_placement) > 0 
) CSI 
-- could join "CSI" to your other tables here, not doing that for this sample 

-- normal date comparison OK here 
WHERE CSI.OriginalDate < GETDATE() 

Для дополнительных очков я включил разницу между DATEDIFF (год, ..) и DATEDIFF (месяц, ..)/12. Последнее лучше, если вы хотите, по крайней мере 12 месяц границы пересекали.

ПРИМЕЧАНИЕ: DATEDIFF считает, что границы пересекаются (2013-12-31 по сравнению с 2014-01-01 = 1 при использовании «года» или «месяца» или «дня» и т. Д.).

+0

См. Мое последнее изменение. – user990016

+0

Я не знаю почему, но используя dateadd вместо датичных работ. – user990016

+0

Как именно вы используете dateAdd? Потому что это не замена DateDiff. – Leigh