SQL Vertica, Cast Long issue - sql

I have the following SQL statement
cast('long', ((substr(D.business_day, 1, 4)||substr(D.business_day, 6, 2))||substr(D.business_day, 9, 2))) AS bdate_id_yyyymmdd,
I have tried to change the 'long' to integer to see if that would work.
cast(integer, ((substr(D.business_day, 1, 4)||substr(D.business_day, 6, 2))||substr(D.business_day, 9, 2))) AS bdate_id_yyyymmdd,
Also tried integer(8)
getting error:
Error: [Vertica][VJDBC](4856) ERROR: Syntax error at or near ","
SQLState: 42601
ErrorCode: 4856

It's not only a syntax error. Vertica is relatively pecky at data types, too.
So you want to make an integer consisting of yyyymmdd from something that looks like an ISO date.
A string?
A date?
There are two ways to go about that. You can't SUBSTR() on a date; you can't call a function getting the day, month, or year, number, from an ISO formatted string.
This example illustrates what you can do. Remember, extracting integers from dates is faster than working with strings and substrings. If your business_day is a DATE type, do what I do with business_date below.
Oh, and Vertica also supports this syntax:
<expression>::INTEGER
to cast to integer.
Happy playing ...
Marco
WITH
d(business_date,business_day) AS (
SELECT DATE '2018-03-04', '2018-03-04'
UNION ALL SELECT DATE '1957-04-22', '1957-04-22'
UNION ALL SELECT DATE '1959-09-27', '1959-09-27'
)
SELECT
CAST(
substr(d.business_day, 1, 4)
||substr(d.business_day, 6, 2)
||substr(d.business_day, 9, 2)
AS int
) AS with_substr
, ( YEAR (business_date)*10000
+ MONTH(business_date)*100
+ DAY (business_date)
) AS with_calc
FROM d;
with_substr|with_calc
20,180,304|20,180,304
19,570,422|19,570,422
19,590,927|19,590,927

Related

Converting decimal to Date

I have a column with dates formatted as decimals, for example: 20,210,830.
I want to convert this number to date format as 08/30/2021
I have tried to use convert and the database shoots me an error that convert is not a valid function. Cast seems to work but, only returns a null value every time.
This statement will validate:
SELECT CAST(CAST(CONTCLMPDTE AS VARCHAR(8)) AS DATE)
FROM CMSFIL.JCTDSC AS COMPLDATE
This statement works but, just outputs null. For background I am querying from a Db2 database.
My ultimate goal is to use this converted date to grab the difference from the current day.
Such as
DAY(CURRENT_DATE) - DAY(COMPLDATE)
Converting it to a date, you cqan do it like this
CREATE TABLE JCTDSC (
CONTCLMPDTE varchar(10)
);
INSERT INTO JCTDSC VALUES ('20,220,830')
SELECT date(to_date(REPLACE(CONTCLMPDTE,',',''),'YYYYMMDD')) FROM JCTDSC AS COMPLDATE
1
2022-08-30
fiddle
So after a long couple days and almost pulling my hair out, here is what worked for me.
SELECT date(substr(CONTCLMPDTE,1,4)||'-'||substr(CONTCLMPDTE,5,2)||'-'||substr(CONTCLMPDTE,7,2)) FROM JCTDSC WHERE COMPANYNUMBER={Company Number} AND JOBNUMBER={Job Number} LIMIT 1
This formatted from yyyymmdd to mm/dd/yyyy. It also worked for finding the days between current_date and CONTCLMPDTE using this code.
DAYS(CURRENT_DATE) - DAYS({COntract Compl Date Formatted})
Thank you all for your help!
You probably get an error because you have some INT / DECIMAL value which can't be converted to a date using this pattern.
The solution is to create some "safe" conversion function "eating" errors like below.
CREATE FUNCTION DATE_SAFE (P_DT INT)
RETURNS DATE
CONTAINS SQL
NO EXTERNAL ACTION
DETERMINISTIC
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
RETURN CAST (NULL AS DATE);
END;
RETURN DATE (TO_DATE (CAST (P_DT AS CHAR (8)), 'YYYYMMDD'));
END
Usage:
SELECT
CONTCLMPDTE
--, DATE (TO_DATE (CAST (CONTCLMPDTE AS CHAR (8)), 'YYYYMMDD'))
, DATE_SAFE (CONTCLMPDTE)
FROM (VALUES 0, 20220830) T (CONTCLMPDTE)
The function returns NULL if the corresponding INT can't be converted to a DATE, and no error is thrown as in case, when you uncomment the commented out line with built-in functions only.
The value just need to be converted into a string with a date format. Then you can use the date() function to convert to date.
create table qtemp/dec_vals (
col1 decimal(8,0) );
insert into qtemp/dec_vals
values (20200830), (20200831), (20200901), (20200902), (20200903), (20200904), (20200905), (20200906);
select date(substr(char(col1), 5, 2) || '/' || substr(char(col1), 7, 2) || '/' || substr(char(col1), 1, 4)) from qtemp/dec_vals;

Redshift can't convert a string to a date, tried multiple functions

I have a table with a field called ADATE, it is a VARCHAR(16) and the values are like so: 2019-10-22-09:00.
I am trying to convert this do a DATE type but cannot get this to work.
I have tried:
1
TO_DATE(ADATE, 'YYYY-MM-DD')
Can't cast database type date to string
2
TO_DATE(LEFT(ADATE, 10), 'YYYY-MM-DD')
Can't cast database type date to string
3
TO_DATE(TRUNC(ADATE), 'YYYY-MM-DD')
XX000: Invalid digit, Value '-', Pos 4, Type: Decimal
4
CAST(ADATE AS DATE)
Error converting text to date
5
CAST(LEFT(ADATE, 10) AS DATE)
Error converting text to date
6
CAST(TRUNC(ADATE) AS DATE)
Error converting numeric to date
The issue was the data containing blanks (not Nulls) so the error was around them.
I resolved this by using the following code:
TO_DATE(LEFT(CASE WHEN adate = '' THEN NULL ELSE adate END, 10), 'YYYY-MM-DD') adate
Clearly, you have bad date string values -- which is why the value should be stored as a date to begin with.
I don't think Redshift has a way of validating the date before attempting the comparison, or of avoiding an error. But you can use case and regular expressions to see if the value is reasonable. This might help:
(case when left(adate, 10) ~ '^(19|20)[0-9][0-9]-[0-1][0-9]-[0-3][0-9]$'
then to_date(left(adate, 10), 'YYYY-MM-DD')
end)
This is not precise . . . you can make it more complex so month 19 is not permitted (for instance), but it is likely to catch the errors.

How can I adjust the Snowflake function to get date with error that it cannot parse?

I'm trying to convert numbers in this format 1180106 to dates.
I've been able to run the following query to get a YYYYMMDD format until today:
TO_DATE(1900 + LEFT(A.ODT_ENTERED_DATE, 3) || SUBSTR(A.ODT_ENTERED_DATE, 4, 4), 'YYYYMMDD')
The inner query builds a number like this: 2018.000000106
But then the TO_DATE function cannot create a date from it. I'm expecting 20180106
Instead I get the following error:
Can't parse '2018.000000106' as date with format 'YYYYMMDD'
If you just run:
select 1900 + LEFT(A.ODT_ENTERED_DATE, 3)
this returns the result as a varchar where the result returned is: 2018.00000
Cast to number in either of the following ways should give you the expected result :
select TO_DATE(1900 + TO_NUMBER(LEFT(1180106, 3))|| SUBSTR(1180106, 4, 4), 'YYYYMMDD')
or
SELECT TO_DATE((1900 + (LEFT(1180106, 3))) :: number || SUBSTR(1180106, 4, 4), 'YYYYMMDD')

query to search dates which are stored as string in the database

I have a table where I store an activity completion date as varchar. The format of the date stored is MM/DD/YYYY HH:MM:SS.
I have search window where I have two fields Completion date from and completion date to.The date format selected here is MM/DD/YYYY.
How do I write a query such that I am able to fetch the activity completion between two given dates from the table which has the dates stores as varchar.This table was created a long time back and no thought was given to saving dates as datetime.
You can use SQL CONVERT to change your columns to DATE format but that will cause performance issues.
SELECT *
FROM MyTable
WHERE CONVERT(DATETIME, MyDate) >= CONVERT(DATE, '01/01/2014')
AND CONVERT(DATETIME, MyDate) <= CONVERT(DATE, '01/31/2014')
CONVERT documentation - http://msdn.microsoft.com/en-us/library/ms187928.aspx
if you are unable to change how data is stored, than for better performance , you can create view with calculated column that converts VARCHAR to DATETIME. After that can create index on calculated column. Index on Computed Column documentation
Use the SUBSTRING function to get the date parts in a comparable order (i.e. yyyymmdd):
select *
from mytable
where
CONCAT( SUBSTRING(thedate, 7, 4) , SUBSTRING(thedate, 4, 2) , SUBSTRING(thedate, 1, 2) )
between
CONCAT( SUBSTRING(#FROMDATE, 7, 4) , SUBSTRING(#FROMDATE, 4, 2) , SUBSTRING(#FROMDATE, 1, 2) )
and
CONCAT( SUBSTRING(#TODATE, 7, 4) , SUBSTRING(#TODATE, 4, 2) , SUBSTRING(#TODATE, 1, 2) )
;
You could use this code :
select * from table_name
where CAST(col1 as date )
between CAST(Completion date from as date )
and CAST(Completion date to as date);
Function syntax CAST:
CAST ( expression AS data_type )
You can use below if the date format is {yyyy-MM-dd}, or you can adjust the charindex's index value depending on format
SELECT *
FROM table
WHERE
CHARINDEX('-', col_value, 0) = 5
AND CHARINDEX('-', col_value, 6) = 8
AND LEN(col_value) = 10
The above piece will look for first occurrence of char '-' at position 5 and the second char '-' at position 8 while the entire date value's length is equal to 10 chars
This is not full proof, but will narrow down the search. If you want to add time then just expand the criteria in the where to accommodate the format i.e. {yyyy-MM-dd 00:00:00.000}
This is a safe way to query the data, without any unexpected 'invalid cast / convert' errors.

Converting a numeric value to date time

I am working in SQL Server 2012. My date column in a data set looks like this: 41547. The column is in nvarchar (255). I want to convert it to something like this: yyyy-mm-dd hh:mm:ss (Example: 2013-09-14 12:23:23.98933090). But I can not do this. I am using following code:
select convert(datetime, date_column, 6)
But this is giving following error:
Msg 241, Level 16, State 1, Line 1 Conversion failed when converting
date and/or time from character string.
What am I doing wrong?
Your date is actually a numeric value (float or integer), stored in a char column. So, you need to convert it to a numerical value (in this case, to float) first, like:
select convert(datetime, CONVERT(float,date_column))
A value of 41547.5 will result in:
`2013-10-02 12:00:00`
The style argument, in your case 6 is only necessary when converting from or to char-types. In this case it is not needed and will be ignored.
NB: The float value is the number of days since 1900-01-01.
e.g. select convert(datetime, CONVERT(float,9.0)) => 1900-01-10 00:00:00; the same as select dateadd(day,9.0,'1900-01-01') would.
The decimal part of the number also equates to days; so 0.5 is half a day / 12 hours.
e.g. select convert(datetime, CONVERT(float,.5)) => 1900-01-01 12:00:00. (Here our comparison to dateadd doesn't make sense, since that only deals with integers rather than floats).
There is an easier way to do it as well.
select convert(date,cast (date_Column+ 19000000 as nvarchar(10)))
as date_Column_Formated
from table_Name
I have just found the way to do this.
First I have to covert the nvarchar to int then I have to convert it to date time. I have used following code:
Select convert(datetime, (convert (int, [date_column])), 6) as 'convertedDateTime' from mytable
6 format is: "dd mon yy"
Like this: SELECT convert(datetime, '23 OCT 16', 6)
Other formats will cause your error
SELECT CONVERT(DATETIME,CONVERT(INT,date_column))