1

I have some data like this in a table:

year           month        day           ID
2013            1             1            x1
2013            1             2            x2
2013            1             3            x3
2013            1             4            x4
2013            1             5            x5
2013            1             6            x6
...
2016            4             10           x1500

This table is a customer table with customerID and customer apply date, but the apply date is split to year & mont & day , data from 2013/1/1 to 2016/4/10 , I want to get the customerID that apply after 2014/4/5.

Here's the code I tried:

SELECT * 
FROM table
WHERE [Year]+'-'+[Month]+'-'+[Day] > '2014-4-5'

But I got this error back:

[Err] 22018 - [SQL Server]Conversion failed when converting the varchar value '2014-4-5' to data type int.

Who can help me?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Walker.li
  • 114
  • 8
  • 1
    Check this, it will be the solution to your issue: http://stackoverflow.com/questions/266924/create-a-date-with-t-sql – David Apr 13 '16 at 09:28
  • @David it is not really a good idea to produce a date from the columns. It will is not sargable – t-clausen.dk Apr 13 '16 at 10:02

5 Answers5

3

This should work and keep your code sargable

SELECT * 
FROM table
WHERE 
  [Year] = 2014 and [Month] = 4 and [Day] > 5
  OR [Year] > 2014
  OR [Year] = 2014 and [Month] > 4

Another useful method would be making a PERSISTED computed column, persisted columns are sargable and you can even put an index on that column:

ALTER TABLE <tablename> ADD actualdate AS 
  CONVERT(date, cast(year as varchar(4))+'-' +
  cast(month as varchar(2)) +'-'+ cast(day as varchar(2)), 126) PERSISTED 

Then you can simply type

WHERE actualdate > '2014-04-05'
Community
  • 1
  • 1
t-clausen.dk
  • 43,517
  • 12
  • 59
  • 92
2

Backs' solution is nice and easy (edit: but incorrect, thanks @t-clausen.dk for pointing that out), a different option would be DATEFROMPARTS():

WHERE DATEFROMPARTS([Year], [Month], [Day]) > '2014-04-05'

Edit: DATEFROMPARTS() is only available in sql-server 2012 and up.

HoneyBadger
  • 14,750
  • 3
  • 34
  • 48
0

This is dependant on language settuings.See this answer for more info..

create table #test
    (
    year int,
    month int,
    date int,
    name char(20)
    )


    insert into #test
    select 2012,1,14,'ab'


    ;with cte
    as
    (
    select *, datefromparts(year,month,date) as datee
     from #test
     )
     select * from cte where date>'somedate'
Community
  • 1
  • 1
TheGameiswar
  • 27,855
  • 8
  • 56
  • 94
0

You have to cast the columns Year, Month and Day to varchar.

Query

SELECT * FROM Customer
WHERE CAST((
  CAST([Year] as varchar(4)) + '-' + 
  CAST([Month] as varchar(2)) + '-' + 
  CAST([Day] as varchar(2)))
) > '2014-04-05';
Ullas
  • 11,450
  • 4
  • 33
  • 50
0

Try this,

SELECT * 
FROM TABLE WHERE
DATEADD(year, [year]-1900, DATEADD(Month, [Month]-1, DATEADD(Day, [Day]-1, 0))) >  CAST('2014-4-5' AS DATETIME)

(OR)

SELECT * 
FROM table
WHERE CAST(CAST([Year]+'-'+[Month]+'-'+[Day] AS VARCHAR(15)) AS DATETIME >  CAST('2014-4-5' AS DATETIME)
Nandhini
  • 344
  • 2
  • 4