I have some sample data in snowflake as follows;
created_at
----------
2022-06-10T18::35::57
2022-06-10T18::35::57
The datatype of this column is VARCHAR(16777216), I am trying to filter for the rows with date June 10,2022. Here is my query;
select *
from table
where to_date(created_at) = date('2022-06-10', 'yyyy-mm-dd');
But this gives me following error; Date '2022-06-10T18::35::57' is not recognized. If we replace to_date by try_to_date then we get 0 rows. Unfortunately I can't go to backend and change the properties of the table. Therefore, I need to resort to sql datetime functions.
Can I please get help here, on how to fix above errors? thanx
Using LEFT to get date part:
where to_date(LEFT(created_at, 10), 'YYYY-MM-DD') = date('2022-06-10', 'YYYY-MM-DD');
There are two issues here -
1 - It is not a date but a timestamp
2 - usage of '::' rather then standard ':' in time portion
Below will not work as its not a date -
with date_cte(created_at) as
(select * from values
('2022-06-10T18::35::57'),
('2022-06-10T18::35::57'))
select to_date('2022-06-10T18::35::57') from date_cte;
100040 (22007): Date '2022-06-10T18::35::57' is not recognized
Using timestamp will not work too due to '::' in time portion
with date_cte(created_at) as
(select * from values
('2022-06-10T18::35::57'),
('2022-06-10T18::35::57'))
select to_timestamp('2022-06-10T18::35::57','yyyy-mm-dd"T"hh24:mi:ss') from date_cte;
100096 (22007): Can't parse '2022-06-10T18::35::57' as timestamp with format 'yyyy-mm-dd"T"hh24:mi:ss'
Below takes care of both -
with date_cte(created_at) as
(select * from values
('2022-06-10T18::35::57'),
('2022-06-10T18::35::57'))
select to_timestamp('2022-06-10T18::35::57','YYYY-MM-DD"T"HH24::MI::SS') from date_cte;
TO_TIMESTAMP('2022-06-10T18::35::57','YYYY-MM-DD"T"HH24::MI::SS')
2022-06-10 18:35:57.000
2022-06-10 18:35:57.000
Now to compare - just convert in desired format using to_char -
with date_cte(created_at) as
(select * from values
('2022-06-10T18::35::57'),
('2022-06-10T18::35::57'))
select * from date_cte
where to_char(to_timestamp('2022-06-10T18::35::57','YYYY-MM-DD"T"HH24::MI::SS'),'yyyy-mm-dd')='2022-06-10';
CREATED_AT
2022-06-10T18::35::57
2022-06-10T18::35::57
One possible way is to do this:
SELECT *
FROM table
WHERE CAST(SUBSTRING(created_at, 0, 11) as date) = '2022-06-10'
Related
I have a date time column in sql DB - named check_time. I want to write a select query where this check_time should be equals to today's date (no need to consider what time is. Only need to check current date).
For example check_time in table is inserted as 03/08/2017 12:00:00.000 AM.
I have written like below
SELECT * FROM time_details
WHERE check_time = DATEADD(day, DATEDIFF(day,0,GETDATE()),0)
But it returns nothing.
This is the correct syntax:
SELECT * FROM time_details where (DATEDIFF(d, check_time, GETDATE()) = 0)
Just CAST the today's date to DATE.
Query
select * from time_details
where check_time = cast(getdate() as date);
Try with
SELECT * FROM time_details where DATE(check_time) =CURDATE()
The DATE function is going to extract just the date from you datetime field while the CURDATE is returning the current date.
Check with the sql query
SELECT * FROM time_details where DATE(check_time)=DATE(NOW())
this should work
SELECT * FROM time_details where check_time =convert(varchar, getdate(), 101)
I have a table TEST with a DATETIME field, like this:
ID NAME DATE
1 TESTING 2014-03-19 20:05:20.000
What I need a query returning this row and every row with date 03/19/2014, no matter what the time is. I tried using
select * from test where date = '03/19/2014';
But it returns no rows. The only way to make it work that I found is to also provide the time portion of the date:
select * from test where date = '03/19/2014 20:03:02.000';
use range, or DateDiff function
select * from test
where date between '03/19/2014' and '03/19/2014 23:59:59'
or
select * from test
where datediff(day, date, '03/19/2014') = 0
Other options are:
If you have control over the database schema, and you don't need the
time data, take it out.
or, if you must keep it, add a computed column attribute that has the time portion of the date value stripped off...
Alter table Test
Add DateOnly As
DateAdd(day, datediff(day, 0, date), 0)
or, in more recent versions of SQL Server...
Alter table Test
Add DateOnly As
Cast(DateAdd(day, datediff(day, 0, date), 0) as Date)
then, you can write your query as simply:
select * from test
where DateOnly = '03/19/2014'
Simple answer;
select * from test where cast ([date] as date) = '03/19/2014';
I am using MySQL 5.6 and there is a DATE function to extract only the date part from date time. So the simple solution to the question is -
select * from test where DATE(date) = '2014-03-19';
http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html
This works for me for MS SQL server:
select * from test
where
year(date) = 2015
and month(date) = 10
and day(date)= 28 ;
select * from test
where date between '03/19/2014' and '03/19/2014 23:59:59'
This is a realy bad answer. For two reasons.
1.
What happens with times like 23.59.59.700 etc.
There are times larger than 23:59:59 and the next day.
2.
The behaviour depends on the datatype.
The query behaves differently for datetime/date/datetime2 types.
Testing with 23:59:59.999 makes it even worse because depending on the datetype you get different roundings.
select convert (varchar(40),convert(date , '2014-03-19 23:59:59.999'))
select convert (varchar(40),convert(datetime , '2014-03-19 23:59:59.999'))
select convert (varchar(40),convert(datetime2 , '2014-03-19 23:59:59.999'))
-- For date the value is 'chopped'.
-- For datetime the value is rounded up to the next date. (Nearest value).
-- For datetime2 the value is precise.
use this
select * from TableName where DateTimeField > date() and DateTimeField < date() + 1
Try this
select * from test where Convert(varchar, date,111)= '03/19/2014'
you can try this
select * from test where DATEADD(dd, 0, DATEDIFF(dd, 0, date)) = '03/19/2014';
There is a problem with dates and languages and the way to avoid it is asking for dates with this format YYYYMMDD.
This way below should be the fastest according to the link below. I checked in SQL Server 2012 and I agree with the link.
select * from test where date >= '20141903' AND date < DATEADD(DAY, 1, '20141903');
Bad habits to kick : mis-handling date / range queries
You can use this approach which truncates the time part:
select * from test
where convert(datetime,'03/19/2014',102) = DATEADD(dd, DATEDIFF(dd, 0, date), 0)
-- Reverse the date format
-- this false:
select * from test where date = '28/10/2015'
-- this true:
select * from test where date = '2015/10/28'
Simply use this in your WHERE clause.
The "SubmitDate" portion below is the column name, so insert your own.
This will return only the "Year" portion of the results, omitting the mins etc.
Where datepart(year, SubmitDate) = '2017'
select *, cast ([col1] as date) <name of the column> from test where date = 'mm/dd/yyyy'
"col1" is name of the column with date and time
<name of the column> here you can change name as desired
select *
from invoice
where TRUNC(created_date) <=TRUNC(to_date('04-MAR-18 15:00:00','dd-mon-yy hh24:mi:ss'));
Test this query.
SELECT *,DATE(chat_reg_date) AS is_date,TIME(chat_reg_time) AS is_time FROM chat WHERE chat_inbox_key='$chat_key'
ORDER BY is_date DESC, is_time DESC
select * from invoice where TRANS_DATE_D>= to_date ('20170831115959','YYYYMMDDHH24MISS')
and TRANS_DATE_D<= to_date ('20171031115959','YYYYMMDDHH24MISS');
SELECT * FROM test where DATEPART(year,[TIMESTAMP]) = '2018' and DATEPART(day,[TIMESTAMP]) = '16' and DATEPART(month,[TIMESTAMP]) = '11'
use trunc(column).
select * from test t where trunc(t.date) = TO_DATE('2018/06/08', 'YYYY/MM/DD')
select *
from employee
where DATEPART(MM ,empDOJ) + DATEPART(yy,empDOJ) < 2013 + 5
I want employee detail from table "employee" where date of join of employee is less than may 2013 but above query is not working properly and "empdoj" is date in sql
correct way of doing this would be
select *
from employee
where empDOJ < convert(date, '20130501', 112)
But you can use string '20130501' or '2013-05-01' because when you compare it to date column, SQL Server will convert data types according to data type priorities. Since date type is higher priority than varchar type, SQL will convert varchar to date implicitly:
select *
from employee
where empDOJ < '20130501'
Note that using functions on your column prevent from using indexes on this column, so when you're writing where datepart(MM ,empDOJ) = 5 index (if you have index on empDOJ column) will not be used.
SELECT *
FROM EMPLOYEE
WHERE EMPDOJ < '2013-05-01'
I have a year column that contains things like 2013, 2012, etc. A month column that displays 1-12, and a day column that contains 1-31. I need to run a select that concatenates them and casts them as an actual date, but I am unsure how to go about this. Can anyone provide some input?
For SQL Server 2008+:
SELECT CONVERT(DATE,CAST([Year] AS VARCHAR(4))+'-'+
CAST([Month] AS VARCHAR(2))+'-'+
CAST([Day] AS VARCHAR(2)))
For SQL Server 2005:
SELECT CONVERT(DATETIME,CAST([Year] AS VARCHAR(4))+
RIGHT('00'+CAST([Month] AS VARCHAR(2)),2)+
RIGHT('00'+CAST([Day] AS VARCHAR(2)),2))
In SQL Server 2012, you will probably be better off avoiding string concatenation or complicated math, as they created a function seemingly just for you:
SELECT DATEFROMPARTS(2013, 8, 19);
Of course, storing the data wrong in the first place can lead to problems - for example, what constraint prevents y = 2013, m = 2 and d = 31 from being in the table? You'd think you could wrap that with TRY_CONVERT(), but not so much:
SELECT TRY_CONVERT(DATE, DATEFROMPARTS(2013, 2, 31));
Error:
Msg 289, Level 16, State 1, Line 3
Cannot construct data type date, some of the arguments have values which are not valid.
So, in order to prevent bad data from getting into these three columns, you will need to use one of the above cumbersome approaches in a check constraint or a trigger...
...or...
...in any version, you could fix the table and store a date (or datetime) in the first place. You get all the benefits of automatic validation as well as intrinsic date/time functionality that you don't get with three separate unrelated integers. Much better off pulling the parts out when you need them separately (with computed columns, a view, or at query time) from a value that is guaranteed to be a date, than try to rely on the individual parts to form a valid date...
SELECT CAST(STR(10000 * Year + 100 * Month + Day) AS DATETIME)
One more, just to fill up list of various approaches:
select
dateadd(d, t.d-1, dateadd(m, t.m-1, dateadd(yy, t.y-1900, 0)))
from (values
(2011, 10, 26)
,(2012, 1, 5)
,(2013, 7, 15)
) t(y, m, d)
You could try something like this if your columns are character columns
Select Cast([year] + '-' + [month] + '-' + [day] as datetime)
From yourTable
If they are numeric you'll need to cast each column to varchar before concatenating otherwise you'll end up getting something funky
Use the Convert function
Select Convert(datetime ,YEAR + '/' + MM + '/' + DAY)
Replace YEAR with your year column, MM with month, and DAY with your day column. and concatenate to formulate your date string
in MySQL
select * from record where register_date like '2009-10-10%'
What is the syntax in SQL Server?
You could use the DATEPART() function
SELECT * FROM record
WHERE (DATEPART(yy, register_date) = 2009
AND DATEPART(mm, register_date) = 10
AND DATEPART(dd, register_date) = 10)
I find this way easy to read, as it ignores the time component, and you don't have to use the next day's date to restrict your selection. You can go to greater or lesser granularity by adding extra clauses, using the appropriate DatePart code, e.g.
AND DATEPART(hh, register_date) = 12)
to get records made between 12 and 1.
Consult the MSDN DATEPART docs for the full list of valid arguments.
There's no direct support for LIKE operator against DATETIME variables, but you can always cast the DATETIME to a VARCHAR:
SELECT (list of fields) FROM YourTable
WHERE CONVERT(VARCHAR(25), register_date, 126) LIKE '2009-10-10%'
Check the MSDN docs for a complete list of available "styles" in the CONVERT function.
Marc
If you do that, you are forcing it to do a string conversion. It would be better to build a start/end date range, and use:
declare #start datetime, #end datetime
select #start = '2009-10-10', #end = '2009-11-10'
select * from record where register_date >= #start
and register_date < #end
This will allow it to use the index (if there is one on register_date), rather than a table scan.
You can use CONVERT to get the date in text form. If you convert it to a varchar(10), you can use = instead of like:
select *
from record
where CONVERT(VARCHAR(10),register_date,120) = '2009-10-10'
Or you can use an upper and lower boundary date, with the added advantage that it could make use of an index:
select *
from record
where '2009-10-10' <= register_date
and register_date < '2009-10-11'
Unfortunately, It is not possible to compare datetime towards varchar using 'LIKE'
But the desired output is possible in another way.
select * from record where datediff(dd,[record].[register_date],'2009-10-10')=0
You can also use convert to make the date searchable using LIKE. For example,
select convert(VARCHAR(40),create_date,121) , * from sys.objects where convert(VARCHAR(40),create_date,121) LIKE '%17:34%'
Try this
SELECT top 10 * from record WHERE IsActive = 1
and CONVERT(VARCHAR, register_date, 120) LIKE '2020-01%'
I am a little late to this thread but in fact there is direct support for the like operator in MS SQL server.
As documented in LIKE help if the datatype is not a string it is attempted to convert it to a string. And as documented in cast\convert documentation:
default datetime conversion to string is type 0 (,100) which is mon dd
yyyy hh:miAM (or PM).
If you have a date like this in the DB:
2015-06-01 11:52:59.057
and you do queries like this:
select * from wws_invoice where invdate like 'Jun%'
select * from wws_invoice where invdate like 'Jun 1%'
select * from wws_invoice where invdate like 'Jun 1 %'
select * from wws_invoice where invdate like 'Jun 1 2015:%'
select * from wws_invoice where invdate like 'Jun ? 2015%'
...
select * from wws_invoice where invdate like 'Jun 1 2015 11:52AM'
you get that row.
However, this date format suggests that it is a DateTime2, then documentation says:
21 or 121 -- ODBC canonical (with milliseconds) default for time,
date, datetime2, and datetimeoffset. -- yyyy-mm-dd hh:mi:ss.mmm(24h)
That makes it easier and you can use:
select * from wws_invoice where invdate like '2015-06-01%'
and get the invoice record. Here is a demo code:
DECLARE #myDates TABLE (myDate DATETIME2);
INSERT INTO #myDates (myDate)
VALUES
('2015-06-01 11:52:59.057'),
('2015-06-01 11:52:59.054'),
('2015-06-01 13:52:59.057'),
('2015-06-01 14:52:59.057');
SELECT * FROM #myDates WHERE myDate LIKE '2015-06-01%';
SELECT * FROM #myDates WHERE myDate LIKE '2015-06-01 11%';
SELECT * FROM #myDates WHERE myDate LIKE '2015-06-01 11:52:59%';
SELECT * FROM #myDates WHERE myDate LIKE '2015-06-01 11:52:59.054%';
Doing datetime searches in SQL server without any conversion to string has always been problematic. Getting each date part is an overkill (which unlikely would use an index). Probably a better way when you don't use string conversion would be to use range checks. ie:
select * from record
where register_date >= '20091010' and register_date < '20091011';
The LIKE operator does not work with date parts like month or date but the DATEPART operator does.
Command to find out all accounts whose Open Date was on the 1st:
SELECT *
FROM Account
WHERE DATEPART(DAY, CAST(OpenDt AS DATE)) = 1`
*CASTING OpenDt because it's value is in DATETIME and not just DATE.
There is a very flaky coverage of the LIKE operator for dates in SQL Server. It only works using American date format. As an example you could try:
... WHERE register_date LIKE 'oct 10 2009%'
I've tested this in SQL Server 2005 and it works, but you'll really need to try different combinations. Odd things I have noticed are:
You only seem to get all or nothing for different sub fields within the date, for instance, if you search for 'apr 2%' you only get anything in the 20th's - it omits 2nd's.
Using a single underscore '_' to represent a single (wildcard) character does not wholly work, for instance, WHERE mydate LIKE 'oct _ 2010%' will not return all dates before the 10th - it returns nothing at all, in fact!
The format is rigid American: 'mmm dd yyyy hh:mm'
I have found it difficult to nail down a process for LIKEing seconds, so if anyone wants to take this a bit further, be my guest!
Hope this helps.
I solved my problem that way. Thank you for suggestions for improvements.
Example in C#.
string dd, mm, aa, trc, data;
dd = nData.Text.Substring(0, 2);
mm = nData.Text.Substring(3, 2);
aa = nData.Text.Substring(6, 4);
trc = "-";
data = aa + trc + mm + trc + dd;
"Select * From bdPedidos Where Data Like '%" + data + "%'";
I realise this an old question, but a lot of the answers here don't give a SARGable answer here, nor cover parmetrisation.
First off, you are far better off using >= and < logic. For the date you want, then that would look like this:
SELECT {Your Columns}
FROM dbo.record
WHERE register_date >= '20091010'
AND register_date < '20091011';
This'll include every time value on 2009-10-10, including the stroke of midnight on the day, and a nanosecond prior to 2009-10-11.
Often, however, you'll be parametrising your query, so instead what you can do is use DATEADD to add a day to the second clause:
DECLARE #DateParam date = '20091010';
SELECT {Your Columns}
FROM dbo.record
WHERE register_date >= #DateParam
AND register_date < DATEADD(DAY,1,#DateParam);
This maintains SARGability and means that any indexes on register_date can be used.