sql date diff in years - varchar列可以为空或null

时间:2014-01-19 22:51:30

标签: sql sql-server sql-server-2005 cfml

我需要创建一份周年纪念报告。这是原始代码;

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,但我收到null或空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,Level 16,State 3,Line 2
  将char数据类型转换为datetime数据类型会导致超出范围的datetime值。

  • 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(年。不正确的条件表达式,[| | | | | | | |比较]条件中的预期之一,

我错过了一些有趣的东西。

1 个答案:

答案 0 :(得分:2)

考虑进行子选择以将date_of_placement格式化为DATETIME,并计算出您希望对date_of_placement为空或空的记录执行的操作。

您可以使用WHERE子句排除这些行,或根据您的需要在将来为他们提供一些任意日期。

完成后,您可以毫无问题地使用日期范围比较,而不是手动比较年份等并遇到边界问题。

<强>更新

根据额外信息,在将这些值输入DATEDIFF之前,使用WHERE子句删除无效条目,例如。

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 vs 2014-01-01 = 1)。