SQL Query Date compare options - sql

I'm trying to compare the current date with database datetime column. I tried the following three options, but no luck. Any idea?
Option 1
select something from tableA
where cast(lastupdateddate as date)=cast(GETDATE() as date)
Option 2
select something from tableA
where CONVERT(date, lastupdateddate)=CONVERT(date, GETDATE())
Option 3
select something from tableA
where CONVERT(VARCHAR(8), lastupdateddate,1)=CONVERT(VARCHAR(8), GETDATE(),1)

Right the first option should already work, provided the column has really datetime datatype, e.g.
create table tablea (
id int,
lastupdateddate datetime
);
and the query
select *
from tablea
where cast(lastupdateddate as date) = cast(getdate() as date)
See SQLFiddle

Related

sql data not returning based on date

i have a column in my database wich stores a date as date/time. I have a sql query to select all records where the date matches the one in the query. but it is not returning any data.
select Name,Dateadded from table
this returns results like
Bob Smith 2009-12-11 09:35:53.000
I changed my query to be the below and no results are returned.
select Name,Dateadded from table where dateadded = '2009-12-11'
I tried the converting to date and still no luck, I have to enter in a date between query to get it working
SELECT
Name, convert(varchar(10), Dateadded , 103)
FROM
table
can anyone tell me where I'm going wrong? I have tried using 'like' and still does not work if I do 'between' two date ranges it works
It may be like this:
WHERE Dateadded >= '2014-07-24' AND Dateadded < '2014-07-25'
WHERE Dateadded >= '2014-07-24' AND Dateadded < DATEADD(dd, 1, '2014-07-24')
or with convert:
WHERE convert(date,Dateadded) = '2014-07-24'
and also you can do something like that
WHERE DAY(Dateadded) = 24 AND MONTH(Dateadded) = 07 AND YEAR(Dateadded) = 2014
Convert datetime to date in your where clause:
select Name,Dateadded
from table
where Convert(date, dateadded) = '2009-12-11'
Casting to date as in other answers will work. For performance, it may be better (depending on indexes) to use:
select Name,Dateadded
from [table]
where dateadded >= '2009-12-11'
and dateadded < '2009-12-12'
Use = only when you expect exact match. In your case you can use :
select Name,Dateadded from table where dateadded like '2009-12-11%'
You can try
select Name,Dateadded from table where date(dateadded) = '2009-12-11'
as you are trying to match only date.
Note : after seeing comments , it seems you are using sql server 2012, above works in mysql not sure about sql server 2012
The following codes will work:
SELECT Name,Dateadded FROM table WHERE Dateadded LIKE '2009-12-11%'
or
SELECT Name,Dateadded FROM table WHERE Dateadded >= '2009-12-11 00:00:00' AND Dateadded <= '2009-12-11 23:59:59'
or
SELECT Name,Dateadded FROM table WHERE Dateadded BETWEEN '2009-12-11 00:00:00' AND '2009-12-11 23:59:59'

force number of rows to return in date range from SQL query

I'm running a query on our SQL (2012) database which returns a count of records in a given date range, grouped by the date.
For example:
Date Count
12/08 12
14/08 19
19/08 11
I need to fill in the blanks as the charts I plot get screwed up because there are missing values. Is there a way to force the SQL to report back a blank row, or a "0" value when it doesn't come across a result?
My query is
SELECT TheDate, count(recordID)
FROM myTable
WHERE (TheDate between '12-AUG-2013 00:00:00' and '20-AUG-2013 23:59:59')
GROUP BY TheDate
Would I need to create a temp table with the records in, then select from that and right join any records from myTable?
Thanks for any help!
If you create a (temporary or permanent) table of the date range, you can then left join to your results to create a result set including blanks
SELECT dates.TheDate, count(recordID)
FROM
( select
convert(date,dateadd(d,number,'2013-08-12')) as theDate
from master..spt_values
where type='p' and number < 9
) dates
left join yourtable on dates.thedate = convert(date,yourtable.thedate)
GROUP BY dates.TheDate
A temp table would do the job but for such a small date range you could go even simpler and use a UNION-ed subquery. E.g:
SELECT dates.TheDate, ISNULL(counts.Records, 0)
FROM
(SELECT TheDate, count(recordID) AS Records
FROM myTable
WHERE (TheDate between '12-AUG-2013 00:00:00' and '20-AUG-2013 23:59:59')
GROUP BY TheDate
) counts
RIGHT JOIN
(SELECT CAST('12-AUG-2013' AS DATETIME) AS TheDate
UNION ALL SELECT CAST('13-AUG-2013' AS DATETIME) AS TheDate
UNION ALL SELECT CAST('14-AUG-2013' AS DATETIME) AS TheDate
UNION ALL SELECT CAST('15-AUG-2013' AS DATETIME) AS TheDate
UNION ALL SELECT CAST('16-AUG-2013' AS DATETIME) AS TheDate
UNION ALL SELECT CAST('17-AUG-2013' AS DATETIME) AS TheDate
UNION ALL SELECT CAST('18-AUG-2013' AS DATETIME) AS TheDate
UNION ALL SELECT CAST('19-AUG-2013' AS DATETIME) AS TheDate
UNION ALL SELECT CAST('20-AUG-2013' AS DATETIME) AS TheDate
) dates
ON counts.TheDate = dates.TheDate
Here's a SQL Fiddle Demo.
If you need a more generic (but also more complex) solution, take a look at this excellent answer (by #RedFilter) to a similar question.

Cast string as date and use it in comparison

I have a table as
NUM | TDATE
1 | 200712
2 | 200708
3 | 200704
4 | 20081210
where mytable is created as
mytable
(
num int,
tdate char(8) -- legacy
);
The format of tdate is YYYYMMDD.. sometimes the date part is optional.
So a date such as "200712" can be interpreted as 2007-12-01.
I want to write query such that i can treat tdate as a Date column and apply date comparison.
like
select num, tdate from mytable where tdate
between '2007-12-31 00:00:00' and '2007-05-01 00:00:00'
So far i tried this
select num, tdate,
CAST(LEFT(tdate,6)
+ COALESCE(NULLIF(SUBSTRING(CAST(tdate AS VARCHAR(8)),7,8),''),'01') AS Date)
from mytable
SQL Fiddle
How can I use the above converted date (3rd column ) for comparison? (needs a join?)
Also is there a better way to do this?
Edit: I have no control over the table scheme for now.. we have suggested the change to the DB team..for now have to stick with char(8) .
I think this a better way to get your fixed date:
SELECT CAST(LEFT(RTRIM(tdate) + '01',8) AS DATE)
You can create a subquery/cte with the date cast properly:
;WITH cte AS (select num, tdate,CAST(LEFT(RTRIM(tdate)+ '01',8) AS DATE)'FixedDate'
from mytable )
select num, FixedDate
from cte
where FixedDate
between '2007-12-31' and '2007-05-01'
Or you can just use your fixed date in the query directly:
select num, tdate
from mytable
where CAST(LEFT(RTRIM(tdate)+ '01',8) AS DATE) between '2007-12-31' and '2007-05-01'
Ideally you would add the fixed date field to your table so that queries can benefit from indexing the date.
Note: Be wary of BETWEEN with DATETIME as the time portion can result in undesired results if you really only care about the DATE portion.
'2007-12-31 00:00:00' > '2007-05-01 00:00:00', so your BETWEEN clause will never return any records.
This will work, with a subquery, and with the dates flipped:
select num, tdate, formattedDate
from
(
select num, tdate
,
CAST(LEFT(tdate,6) + COALESCE(NULLIF(SUBSTRING(CAST(tdate AS VARCHAR(8)),7,8),''),'01') AS Date) as formattedDate
from mytable
) a
where formattedDate between '2007-05-01 00:00:00' and '2007-12-31 00:00:00'
sqlFiddle here
I think you should avoid storing date in string type fields. If that is something you have to live with try following solution.
Since you are having yyyymmdd or yyyymm format you can first get them all in yyyymmdd format which is Culture independent ISO format and then use style 112 to convert into Date for comparison:
--Culture independent solution
;with cte as (
select num, tdate,
convert(date,left(rtrim(tdate) + '01',8),112) mydate --yyyymmdd format
from mytable
)
select num,tdate,mydate
from cte
where mydate between convert(date,'20071231',112) and --Values are in yyyymmdd format
convert(date,'20070501',112)
Yet another way to turn your string values into dates would be to use REPLACE:
SELECT num, tdate
FROM mytable
WHERE CAST(REPLACE(tdate, ' ', '01') AS date) BETWEEN #date1 AND #date2
;
If you really want to both return the converted date value and use it for filtering, you can employ CROSS APPLY to avoid repeating the logic:
SELECT t.num, t.tdate, x.date
FROM mytable AS t
CROSS APPLY (SELECT CAST(REPLACE(t.tdate, ' ', '01') AS date)) AS x (date)
WHERE x.date BETWEEN #date1 AND #date2
;
This method assumes that your char(8) strings are formatted as either YYYYMMDD or YYYYMM, although the method will work without any changes if you decide to start using values formatted as just YYYY in addition to the other two formats (to imply the beginning of a year, just like a YYYYMM implies the beginning of a month).
with date_cte(num,date)as
(select num,CAST(LEFT(tdate,6)
+ COALESCE(NULLIF(SUBSTRING(CAST(tdate AS VARCHAR(8)),7,8),''),'01') AS Date)
from mytable)
select t1.num, t1.tdate,t2.date
from mytable t1 join date_cte t2 on t1.num=t2.num
where t2.date
between '2007-12-31 00:00:00' and '2007-05-01 00:00:00'
I don't have the time to test right now, but something like this may work...
select num, tdate
from mytable
WHERE CAST(LEFT(tdate,6)
+ COALESCE(NULLIF(SUBSTRING(CAST(tdate AS VARCHAR(8)),7,8),''),'01') AS Date) BETWEEN CAST('2007-12-31 00:00:00' as smalldatetime) and CAST('2007-05-01 00:00:00' as smalldatetime)
My proposal would be to add a date field to your table. If your table is regularly updated, fill it from the legacy field through a stored proc on a regular schedule (either trigger or job).
You'll then be able to use the date as ... a date, without all these tricks, turnarounds, and other approximations which are all potential source for confusion, mistakes and questionable results.

List rows after specific date

I have a column in my database called "dob" of type datetime. How do I select all the rows after a specific DoB in SQL Server 2005?
Simply put:
SELECT *
FROM TABLE_NAME
WHERE
dob > '1/21/2012'
Where 1/21/2012 is the date and you want all data, including that date.
SELECT *
FROM TABLE_NAME
WHERE
dob BETWEEN '1/21/2012' AND '2/22/2012'
Use a between if you're selecting time between two dates
Let's say you want to get all records from a table called Table_One with a datetime column called date_value that have happened in the past six months...
CREATE TABLE (
date_value DATETIME
)
SELCECT *
FROM Table_One
WHERE date_value > DATEADD(month, -6, getdate());
This gives a bit more dynamic of a solution.

sort distinct date column

I need distinct year and month from date column which would be sorted by same column.
I have date coulmn with values like (YYYY/MM/DD)
2007/11/7
2007/1/8
2007/11/4
2007/12/3
2008/10/4
2009/11/5
2008/5/16
after having query, it should be
2007/1/1
2007/11/1
2007/12/1
2008/5/1
2008/10/1
2009/11/1
This doesn't seems to be working
SELECT distinct (cast(year(datecol) as nvarchar(20) ) +
'/'+ cast(month(datecol) as nvarchar(20) ) + '/1') as dt1
FROM Table
ORDER BY dt1
Soemthing like this would work on MS SQL Server:
select
distinct
dateadd(day, -1 * DAY(datefield) + 1, datefield)
From
datetable
order by
dateadd(day, -1 * DAY(datefield) + 1, datefield)
The DATEADD function call basically subtracts (day-1) DAYS from the current date --> you always get the first of whatever month that date is in.
Sort by it and you're done! :-)
ADditionally, you could also add this functionality to your table as a "computed column" and then use that for easy acccess:
alter table yourTable
add FirstOfMonth As DATEADD(day, -1 * DAY(datefield) + 1, datefield) persisted
Then your query would be even simpler:
SELECT DISTINCT FirstOfMonth
FROM YourTable
ORDER BY FirstOfMonth
Marc
When dealing with dates in SqlServer avoid using cast like this - the resulting format will change depending on server config.
Instead use convert and choose a format (for instance 112) that adds leading zeros to the month.
Anil,
Do you also have time part in the dates ? What dataType are you using for the column ? Are you
using DateTime dataType or Char ?
This works for me
SELECT DISTINCT (DateField) AS Date FROM DateTable ORDER BY 1