Compare a date with specific date format - sql-server

I have column of type varchar in a table and have different type of date format in it. I want to compare it with specific format of date. If it is true then those rows should be returned only. Format of the date is 'yyyymmdd'
e.g., 20200831 = 'yyyymmdd'
dates are in below format
20200831
31/Aug/2020
08-31-2020
2020-08-31
These are few date format which are present in the table.

If I understand the question correctly, a possible solution is the following statement:
SELECT DateText
FROM (VALUES
('20200831'),
('31/Aug/2020'),
('08-31-2020'),
('2020-08-31')
) v (DateText)
WHERE CONVERT(varchar(8), TRY_CONVERT(date, DateText), 112) = DateText
Result:
DateText
20200831

SELECT *
FROM tableName
WHERE ISDATE(dateCol) = 1 AND ISNUMERIC(dateCol) = 1;
ISDATE() function returns 1 if column value is valid SQL Server date
and ISNUMERIC() returns 1 if column value is valid number, so 20200831 satisfies both conditiion.

If you are using SQL Server 2012 or later, then the TRY_CONVERT function is one option here:
SELECT
dt,
TRY_CONVERT(datetime, dt) AS dt_out
FROM yourTable
WHERE
TRY_CONVERT(datetime, dt) = '2020-08-31';
Demo
Data:
WITH yourTable AS (
SELECT '20200831' AS dt UNION ALL
SELECT '31/Aug/2020' UNION ALL
SELECT '08-31-2020' UNION ALL
SELECT '2020-08-31'
)

Related

Extracting date from varchar with timezone in snowflake

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'

CONVERT fails but TRY_CONVERT successfully convert same data

I have a column with dates stored as strings (NVARCHAR(500)), in dd/MM/yyyy format.
This query gets all rows with a non null value in my date_column, 13955 rows returned, 18359 total rows on table.
SELECT ID, date_column
FROM [MyTable] WITH(NOLOCK)
WHERE
client = 178425
AND folder = 1422720
AND date_column IS NOT NULL
Filtering for rows that successfully converted the string to a date value using TRY_CONVERT. Returned all 13955 rows, indicating all of them are valid dates.
SELECT ID, date_column
FROM [MyTable] WITH(NOLOCK)
WHERE
client = 178425
AND folder = 1422720
AND date_column IS NOT NULL
AND TRY_CONVERT(DATE, date_column, 103) IS NOT NULL
Now converting the column to a date in the select statement, again no errors and all 13955 rows returned.
SELECT ID, CONVERT(DATE, date_column, 103)
FROM [MyTable] WITH(NOLOCK)
WHERE
client = 178425
AND folder = 1422720
AND date_column IS NOT NULL
AND TRY_CONVERT(DATE, date_column, 103) IS NOT NULL
So I assumed all NON-NULL values are valid dates, right?
But then if I remove the TRY_CONVERT from the where statement, I receive an error:
Conversion failed when converting date and/or time from character string.
SELECT ID, CONVERT(DATE, date_column, 103)
FROM [MyTable] WITH(NOLOCK)
WHERE
client = 178425
AND folder = 1422720
AND date_column IS NOT NULL
How can this be? ALL Non NULL rows are valid dates but only if I use TRY_CONVERT function there?
Any ideas on how to find the faulty values in my table?
PS. Not providing sample data because all tests I did out of this specific table worked as expected. I have no Idea what is causing this problem...

Why it is returning the date which is not between the range?

I want to only display the data in between 15 to 23 May 2019. But why it is also returning the data which is not between the date range?
Below is my query
SELECT Appointment_ID,
WO_DespatchName, Despatch_Name AS WO_selectDespatchName,
FORMAT(Appointment_DateTime, 'dd/MMM/yyyy hh:mm tt') AS Appointment_DateTime,
FORMAT(Appointment_ProposalSent, 'dd/MMM/yyyy') AS Appointment_ProposalSent,
WO_MaidName, Maid_Name AS WO_selectMaidName,
Appointment_Location, Appointment_FaceToFace, Appointment_Service, Appointment_Remarks, WO_Duration,
Appointment_ContactID, Contact_Name AS Appointment_selectContactID
FROM Appointments A
LEFT JOIN Despatch ON Despatch_ID = WO_DespatchName
LEFT JOIN CustomerDetails ON Contact_ID = Appointment_ContactID
LEFT JOIN Maid ON Maid_ID = WO_MaidName
WHERE FORMAT(Appointment_DateTime, 'dd/MM/yyyy') BETWEEN '15/05/2019' AND '23/05/2019'
AND (A.IsDelete = 0 OR A.IsDelete IS NULL)
ORDER BY CONVERT(DateTime, Appointment_DateTime,101) ASC
The output that I get is this https://drive.google.com/file/d/1VnrSET1V1eoFvEUUtRwXtQmKGWamURgV/view?usp=sharing
You are comparing texts, not dates. So it will return any row where date converted to string starts between 15 and 23.
You need to use date datatype in your comparison:
WHERE Appointment_DateTime >= CAST('20190515' AS date) AND Appointment_DateTime < CAST('20190524' AS date)
Please notice I added one day to the end range, so 05/23/2019 11:59:59.9... PM still will be accepted. CAST as date is not necessary, but improves readability.
The problem is in your where clause. Since your Appointment_DateTime is in datetime format. I am expecting that this column has value type datetime.
Now come to your query, '23/05/2019' is simple string, so unable to compare this as datetime. First you need to convert your from and to date into datetime format.
Please try this (if only date matching is your concern):
SELECT Appointment_ID,
WO_DespatchName, Despatch_Name AS WO_selectDespatchName,
FORMAT(Appointment_DateTime, 'dd/MMM/yyyy hh:mm tt') AS Appointment_DateTime,
FORMAT(Appointment_ProposalSent, 'dd/MMM/yyyy') AS Appointment_ProposalSent,
WO_MaidName, Maid_Name AS WO_selectMaidName,
Appointment_Location, Appointment_FaceToFace, Appointment_Service, Appointment_Remarks, WO_Duration,
Appointment_ContactID, Contact_Name AS Appointment_selectContactID
FROM Appointments A
LEFT JOIN Despatch ON Despatch_ID = WO_DespatchName
LEFT JOIN CustomerDetails ON Contact_ID = Appointment_ContactID
LEFT JOIN Maid ON Maid_ID = WO_MaidName
WHERE FORMAT(Appointment_DateTime, 'dd/MM/yyyy') BETWEEN FORMAT('15/05/2019', 'dd/MM/yyyy') AND FORMAT('23/05/2019', 'dd/MM/yyyy')
AND (A.IsDelete = 0 OR A.IsDelete IS NULL)
ORDER BY CONVERT(DateTime, Appointment_DateTime,101) ASC
Or you may try convert to convert your string into datetime format.
Feel free to ask for any further confusion.

How to check date time column value equals to current date in sql where clause

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)

How to query DATETIME field using only date in Microsoft SQL Server?

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')

Resources