convert string from MM/DD/YYYY to YYYYMMDD - pervasive

My date column is stored as a CHAR and in YYYYMMDD format. The string I have to search from this column is in MM/DD/YYYY format. How could I change it to YYYYMMDD. Also if my parametr is passed NULL to the query I do not include the DOB search in the WHERE clause
select *
from ona
left join mnv on ona.xyz = mnv.xyz
where (coalesce(to_date(mnv.DOB,'YYYYMMDD'),to_date('1901-01-01','YYYY-MM-DD')) OR '{BirthDate}' IS NULL)

It is not suggested to store dates as string, mainly due to this particular reason. So try to change your column datatype if possible to avoid this in future.
For now, you can compare it, by converting both of the strings to date, with to_date function.
select something from some_table where
to_date(date_Column,'YYYYMMDD')=to_date(search_value,'MM/DD/YYYY');
As you asked in comments, it is possible to do it by manupulating the strings also however I think comparing by dates would be faster and less prone to inaccuracy.
Update after seeing your query.
You are not converting BirthDate to date and also there is no = to compare in your query. Assuming that BirthDate is a string with MM/DD/YYYY format, use something like below.
select * from ona left join mnv on ona.xyz = mnv.xyz
where
to_date(mnv.DOB,'YYYYMMDD') = to_date(BirthDate,'MM/DD/YYYY')
and mnv.DOB is not null
and BirthDate is not null.

Related

How to convert different date formats to single one in snowflake

I have test table where column sys_created_on(datatype is varchar(15)) is a datetime field and we receive two different date formats like below.
03-04-2022 12:49
2/28/2022 10:35
Expected Result is:
03-04-2022 12:49
02-28-2022 10:35
Could you please suggest if there is any way to convert all formats to one format instead..
any suggestions can be appreciated. Please suggest if datatype change can help anything here.
Thank you!!
The best thing to do here would be to just convert your text timestamp column to a bona fide timestamp column. You could achieve this using the TO_TIMESTAMP() function along with a CASE expression:
SELECT
ts,
CASE WHEN REGEXP_LIKE(ts, '\\d{1,2}-\\d{2}-\\d{4} \\d{1,2}:\\d{2}')
THEN TO_TIMESTAMP(ts, 'mm-dd-yyyy hh24:mi')
ELSE TO_TIMESTAMP(ts, 'mm/dd/yyyy hh24:mi') END AS ts_real
FROM yourTable;
Assuming you had a new timestamp column, you could populate it using the ts text column as follows:
UPDATE yourTable
SET ts_real = CASE WHEN REGEXP_LIKE(ts, '\\d{1,2}-\\d{2}-\\d{4} \\d{1,2}:\\d{2}')
THEN TO_TIMESTAMP(ts, 'mm-dd-yyyy hh24:mi')
ELSE TO_TIMESTAMP(ts, 'mm/dd/yyyy hh24:mi') END;
TRY_TO_DATE return null if it fails so you can just chain different formats together with COALESCE or NVL
SELECT column1,
TRY_TO_DATE(column1, 'dd-mm-yyyy hh:mi') as d1,
TRY_TO_DATE(column1, 'mm/dd/yyyy hh:mi') as d2
,nvl(d1,d2) as answer
FROM VALUES ('03-04-2022 12:49'),('2/28/2022 10:35');
gives:
COLUMN1
D1
D2
ANSWER
03-04-2022 12:49
2022-04-03
2022-04-03
2/28/2022 10:35
2022-02-28
2022-02-28
which can be merged as
,nvl(TRY_TO_DATE(column1, 'dd-mm-yyyy hh:mi'),TRY_TO_DATE(column1, 'mm/dd/yyyy hh:mi')) as answer
ah, didn't read well enough, to make them all the same, UPDATE but use the "local format" thus just a TO_CHAR
thus:
UPDATE table
SET sys_created_on = to_char(nvl(
TRY_TO_TIMESTAMP(sys_created_on , 'dd-mm-yyyy hh:mi'),
TRY_TO_TIMESTAMP(sys_created_on , 'mm/dd/yyyy hh:mi')
));
Replace the separator using replace():
update test_table
set sys_created_on = replace(sys_created_on,'/','-');
If you're also dealing with different day and month field order, look into regexp_replace() to swap their places:
update test_table
set sys_created_on = regexp_replace(sys_created_on,
'(.*)/(.*)/(.*)',
'\\2-\\1-\\3');
That's in case your 03-04-2022 is in format dd-mm-yyyy making it April 3rd, not March 4th. It's good to know what exact format you're dealing with. In extreme cases you might even need to make sure whether your hour field is 24-h or 12-h-based but missing an am/pm meridiem indicator.
As suggested by Tim's and Simeon's answers, a matching data type is always encouraged. It takes less space, queries faster, enables type-specific functions and maintains validity of data (varchar doesn't care if you get February 30th or 32nd day of month 13, at 25:60)
If you want to keep the cookie and eat it too, here's how you can add one virtual column where you'll always see a standardised version of your sys_created_on, and another one, which will always interpret it as a proper timestamp. This way you don't need to touch anything in how the table is populated, keep the original, unprocessed data, see how it gets standardised, and also benefit from a timestamp data type, while not using up any additional space:
alter table test_table
add column standardised_sys_created_on varchar(15)
as replace(sys_created_on,'/','-'),
add column timestamp_sys_created_on TIMESTAMP_NTZ
as coalesce(
try_to_date(sys_created_on, 'dd-mm-yyyy hh24:mi'),
try_to_date(sys_created_on, 'dd/mm/yyyy hh24:mi'));
To make it faster at the expense of materializing them, you can turn those virtual columns into generated/computed using default.

Date convertion Issue in Ms sql

My table name as tbl_event
Event_ExpiryDate, Event_Date fields data type is varchar, I have using the following query for getting data from the table:
select * from tbl_event
WHERE
LEFT (CONVERT(VARCHAR,Event_ExpiryDate,103),12)>= LEFT(CONVERT(varchar,GetDate(),103),12) and
LEFT (CONVERT(VARCHAR,Event_Date,103),12)<= LEFT(CONVERT(varchar,GetDate(),103),12)
but I am getting a result like this
1 data to be missing. Why? this issue only on some month's date only. Months are 2,4,8,12
The real problem here is your data, and that you're using the wrong data type. Fix the data type, fix the problem.
You can fix that by firstly changing your varchar representation of a date to an unambiguous Date format, yyyyMMdd (This assumes your dates are in the format dd/MM/yyyy):
UPDATE dbo.tbl_event
SET Event_Date = CONVERT(varchar(8),CONVERT(date,Event_Date,103),112),
Created_Date = CONVERT(varchar(8),CONVERT(date,Created_Date,103),112),
Event_ExpiryDate = CONVERT(varchar(8),CONVERT(date,Event_ExpiryDate,103),112);
Then you can ALTER the table to fix your data types:
ALTER TABLE dbo.tbl_event ALTER COLUMN Event_Date date NULL; --Use NOT NULL if not NULLable
ALTER TABLE dbo.tbl_event ALTER COLUMN Created_Date date NULL; --Use NOT NULL if not NULLable
ALTER TABLE dbo.tbl_event ALTER COLUMN Event_ExpiryDate date NULL; --Use NOT NULL if not NULLable
Note: If any of your dates have bad values, for example '31/04/2019', the above will fail. You can get around this by changing the CONVERT functions to TRY_CONVERT, however any values that fail to convert will have the value NULL. If your columns have the NOT NULL property you will need to ensure you handle that too. If you do have bad values in your table, I strongly suggest taking a backup, or copy of the database/table first, so that you have a historical copy. (Of course, does a date like '31/04/2019' or '12/13/2018' have any meaning anyway?)
You can use only convert() :
where convert(date, Event_ExpiryDate, 103) >= convert(date, getdate()) and
convert(date, Event_Date, 103) <= convert(date, getdate());
However, storing varchar date is really bad idea. It will lead you lots of in trouble.

Select condition on date for datetime field

I want to impose date condition on a date time field in SQL Server.
The datetime field is like this 2011-01-19 17:57:18.350 and when I execute below query it yields no results.
select top 1000 *
from [dbo].[RouteState]
where convert (date, logtime, 101) = '12-01-2015'
Can someone help me what's going wrong here?
There is no need to convert the datetime column to anything. Use a closed-open interval instead and change the format of your string literal to yyyymmmdd to make sure that SQL Server will interpret the date value in the same way regardless of regional and date format settings.
select top 1000 *
from [dbo].[RouteState]
where logtime >= '20150112' and
logtime < '20150113';
For more info on casting a column to date you can have a look at Cast to date is sargable but is it a good idea?

date between query issue in sqlite3

In my data base , i was stored one student data in the following date format is 07-03-2013(dd-mm-yyyy). For example the start date greater than the end date ,no row return in the results.
For Ex.
select student_name from general_details where join_date between '11-02-2013' and '08-03-2013'
it returns 0
if start date less than the end date
select student_name from general_details where join_date between '01-02-2013' and '08-03-2013'
it returns row value 1;
Please suggest ,thanks in advance
The dates are compared alphabetically and not as datetime stamps.
If you can influence how the dates are stored, use a format such as ISO-8601 yyyy-MM-dd or unix epoc timestamps to make the comparisons work.
If you cannot influence the data, you can convert the values in SQL by picking up the components with substr() and concatenating together with ||, like this:
substr(join_date,7,4) || substr(join_date,4,2) || substr(join_date,1,2)

How do I convert date in Netezza to yyyymmdd from timestamp format?

How do I convert date in Netezza to yyyymmdd from timestamp format?
Use the below queries to convert to date format.
select TO_CHAR( DATE '2009-12-23 23:45:58','YYYY-MM-DD')
or
select TO_CHAR(TO_DATE( '2009-12-23 23:45:58','YYYY-MM-DD HH24:MI:SS'),'YYYY-MM-DD')
or
select TO_CHAR(current_timestamp,'YYYY-MM-DD')
Netezza has built-in function for this by simply using:
SELECT DATE(STATUS_DATE) AS DATE,
COUNT(*) AS NUMBER_OF_
FROM X
GROUP BY DATE(STATUS_DATE)
ORDER BY DATE(STATUS_DATE) ASC
This will return just the date portion of the timetamp and much more useful than casting it to a string with "TO_CHAR()" because it will work in GROUP BY, HAVING, and with other netezza date functions. (Where as the TO_CHAR method will not)
Also, the DATE_TRUNC() function will pull a specific value out of Timestamp ('Day', 'Month, 'Year', etc..) but not more than one of these without multiple functions and concatenate.
DATE() is the perfect and simple answer to this and I am surprised to see so many misleading answers to this question on Stack. I see TO_DATE a lot, which is Oracle's function for this but will not work on Netezza.

Resources