I am querying tables from Microsoft SQL 2008 which have date split across 3 columns: day, month and year. Unfortunately, I do not have control over this because data is coming in to the database daily from a 3rd party 开发者_如何学Csource in that format.
I need to add between to a where clause so user can pull records within a range. Would be easy enough if date was in a single column but finding it nearly impossible when its split across three columns.
To display the date, I am doing a
CAST(
CAST(year as varchar(4)) + '-' +
CAST(month as varchar(2)) + '-' +
CAST(day as varchar(2))
as date) AS "date"`
in a select. I tried to put it as a parameter for datediff function or just the regular between but get no results.
Without access to change the table, you can use a subquery to construct the date before the filtration is applied:
SELECT x.*
FROM (SELECT CAST(CAST(year as varchar(4)) + '-' +
CAST(month as varchar(2)) + '-' +
CAST(day as varchar(2)) AS date) AS [date]
...
FROM ...) x
WHERE x.[date] BETWEEN ? AND ?
If using SQL Server 2005+, you can use a Common Table Expression (CTE) instead -- but there's no performance difference between using a CTE vs the subquery approach:
WITH example AS (
SELECT CAST(CAST(year as varchar(4)) + '-' +
CAST(month as varchar(2)) + '-' +
CAST(day as varchar(2)) AS date) AS [date]
...
FROM ...)
SELECT x.*
FROM example x
WHERE x.[date] BETWEEN ? AND ?
Caveats:
Because the dates are being constructed on the fly, this will never perform as well as if the values were stored as DATE or DATETIME -- an index on the year, month or day columns can not be utilized. Options to consider would be an indexed view (AKA materialized view), or computed column.
Perhaps consider adding a Computed Column if searching for dates/ranges is a common requirement
精彩评论