Snowflake: Conversion error of an teradata query to snow sql - sql

I have a Teradata query (updated the fields with sample values):
select (case '-' when '-' then '-' ||'04' || ':' ||'00'
else '04' || ':' ||'00'
end (Interval hour to minute)) +
(case
'2400' when '2400' then 24
else 0
end (interval hour));
output : -04:00 (varchar type)
select (case '-' when '-' then '-' ||'04' || ':' ||'00'
else '04' || ':' ||'00'
end (Interval hour to minute)) +
(case
'1835' when '2400' then 24
else 0
end (interval hour));
output: 20:00 (varchar type)
Want to convert the same in snowflake, but the same output value was not able to insert in snowflake varchar column:
SELECT
(CASE SUBSTR(raw_data, 48, 1)
WHEN '-' THEN CONCAT('-' , SUBSTR(raw_data,49,2) , ':' , SUBSTR(raw_data,51,2))
ELSE CONCAT(SUBSTR(raw_data,49,2) , ':' , SUBSTR(raw_data,51,2)) END) +
(CASE SUBSTR(raw_data,40,4) WHEN '2400' THEN 24 ELSE 0 END)
AS COLUMN_1
FROM
(SELECT temp_row.$1 as raw_data from
#JOB_MANAGEMENT.SNOWFALKE (file_format => 'DB.TBL_FILE_FORMAT',
pattern=>'.*/input_file.txt') temp_table) temp;
Sample:
SELECT
(CASE '-' WHEN '-'
THEN CONCAT('-' , '04 , ':' , '00')
ELSE CONCAT('04' , ':' , '00') END) +
(CASE '1825' WHEN '2400' THEN 24 ELSE 0 END)
Output : -04:00 (column type - varchar) -> but throwing error in snowflake.
Numeric value '-04:00' is not recognized

Instead of trying to rewrite query 1:1, this approach focuses on rewriting the logic using TIME_FROM_PARTS:
SELECT
CASE WHEN SUBSTR(raw_data, 48, 1) = '-'
THEN TIME_FROM_PARTS(24-SUBSTR(raw_data,49,2)::INT, SUBSTR(raw_data,51,2)::INT, 0)
ELSE TIME_FROM_PARTS(SUBSTR(raw_data,49,2)::INT, SUBSTR(raw_data,51,2)::INT, 0)
END
FROM ...

Related

How to store -00:00 time zone value in snowfkale

I had a scenario in storing the data reading from source file to snowflake table:
Input data line:
3 AC 0060876543NOV221080123 23 5 7 56709000900+0900
I have to read the last four digit in "09:00" format based on the plus or minus symbol. If the data coming as -0900 then in snowflake it should store as "-09:00".
SELECT
(CASE SUBSTR(raw_data, 48, 1)
WHEN '-' THEN CONCAT('-' , SUBSTR(raw_data,49,2) , ':' , SUBSTR(raw_data,51,2))
ELSE CONCAT(SUBSTR(raw_data,49,2) , ':' , SUBSTR(raw_data,51,2)) END) +
(CASE SUBSTR(raw_data,40,4) WHEN '2400' THEN 24 ELSE 0 END)
AS COLUMN_1
FROM
(SELECT temp_row.$1 as raw_data from
#JOB_MANAGEMENT.SNOWFALKE (file_format => 'DB.TBL_FILE_FORMAT',
pattern=>'.*/input_file.txt') temp_table) temp;
But, I'm getting error as below :
For minus value : Numeric value '-04:00' is not recognized
For plus value: Numeric value '09:00' is not recognized
UPDATED:
This is my teradata sql:
select (case '-' when '-' then '-' ||'04' || ':' ||'00'
else '04' || ':' ||'00'
end (Interval hour to minute)) +
(case
'2400' when '2400' then 24
else 0
end (interval hour));
output : -04:00
select (case '-' when '-' then '-' ||'04' || ':' ||'00'
else '04' || ':' ||'00'
end (Interval hour to minute)) +
(case
'1835' when '2400' then 24
else 0
end (interval hour));
output: 20:00
I want to implement the same in snowflake and thus in the second case statement it is throwing error.
The final column which I need to store the content in varchar column.
SUBSTR(raw_data, LEN(raw_data)-5,3) || ':' || RIGHT(raw_data,2)

Sql between query trying to get DATETIME column and not the condition

I'm trying to filter between two DateTimes allowing null values too
I'm using OdbcDataAdapter
objCon = new OdbcConnection(connStr05);
objDA = new OdbcDataAdapter(query, objCon);
The connection is working fine because I use it for another select queries.
And I'm filling a datatable with that info
DataTable objDTfinal = new DataTable();
objDA.Fill(objDTfinal);
I've tested different queries...
This one works (don't crash when start filling) but it crashes showing this error:
Year, Month, and Day parameters describe an un-representable DateTime Exception
"SELECT * FROM DBName.PUB.gvehicu
where (( \"GVVE-fecmat\" BETWEEN '1753-01-01'
AND '2500-12-31' or ( \"GVVE-fecmat\" IS NULL ))
and (( \"GVVE-finiga\" BETWEEN '1753-01-01'
AND '2500-12-31') OR ( \"GVVE-finiga\" IS NULL )))"
The same query without null condition get half of the results but its working and filling it all fine.
My boss told me that when he works with dates, he uses Convert(DATETIME, value) so I tried this way too
But this query automatically throws an error that cannot find the column DATETIME
"SELECT * FROM DBname.PUB.gvehicu
where (( \"GVVE-fecmat\" BETWEEN CONVERT(DATETIME,'1753-01-01')
AND CONVERT(DATETIME,'2500-12-31')) or ( \"GVVE-fecmat\" IS NULL ))
and (( \"GVVE-finiga\" BETWEEN CONVERT(DATETIME,'1753-01-01')
AND CONVERT(DATETIME,'2500-12-31')) OR ( \"GVVE-finiga\" IS NULL ))"
System.Data.Odbc.OdbcException: 'ERROR [42S22] [DataDirect][ODBC Progress OpenEdge Wire Protocol driver][OPENEDGE]Column "DATETIME" cannot be found or is not specified for query. (13865)'
I'm not sure if it should work with convert and I'm doing something wrong, or there is another way to get this.
I'm trying to get automatically all table values with one operation to fill a DataTable object that I will throw to another table with SqlBulkCopy, that's why I'm using this way to work.
The source database is a Progress that I'm accessing with odbc connection and the ending database is SQL
I've finally found the solution.
With progress database you have to pass the datatimes in different format.
Passing datetimes without convert and in this format worked for me: 'YYYY-mm-dd', but if you have the year, month or day into a variable you have to pass like '#YEAR#' + '-' + '#MONTH#' + '-' + '01'
Because there is a lot of information and it still crashes because timeout, I've done different ranges of datetimes to solve it.
SELECT * FROM AUTO05AS.PUB.rhiscab where "RHMC-fecmov" < '1900-01-01'
SELECT * FROM AUTO05AS.PUB.rhiscab where "RHMC-fecmov" < '2000' + '-' + '01' + '-' + '01' AND "RHMC-fecmov" > '1900' + '-' + '01' + '-' + '01'
SELECT * FROM AUTO05AS.PUB.rhiscab where "RHMC-fecmov" < '2010' + '-' + '01' + '-' + '01' AND "RHMC-fecmov" > '2000' + '-' + '01' + '-' + '01'
SELECT * FROM AUTO05AS.PUB.rhiscab where "RHMC-fecmov" < '2015' + '-' + '01' + '-' + '01' AND "RHMC-fecmov" > '2010' + '-' + '01' + '-' + '01'
SELECT * FROM AUTO05AS.PUB.rhiscab where "RHMC-fecmov" < '2020' + '-' + '01' + '-' + '01' AND "RHMC-fecmov" > '2015' + '-' + '01' + '-' + '01'
SELECT * FROM AUTO05AS.PUB.rhiscab where "RHMC-fecmov" > '2020-01-01'
From the exception it is clear that query builder is looking for "DATETIME" as column in table, which means first parameter must be value. change the query as below and try.
"SELECT * FROM DBname.PUB.gvehicu
where (( \"GVVE-fecmat\" BETWEEN CONVERT('1753-01-01', DATETIME)
AND CONVERT('2500-12-31', DATETIME)) or ( \"GVVE-fecmat\" IS NULL ))
and (( \"GVVE-finiga\" BETWEEN CONVERT('1753-01-01' , DATETIME)
AND CONVERT('2500-12-31', DATETIME)) OR ( \"GVVE-finiga\" IS NULL ))"

How to do the Calculation by using Date format in Oracle SQL

Appreciate your help for the below question, i have struggle for a long time for this question. Please look at the example below.
(SELECT MIN(CASE WHEN SI.DATE_STAT >= 78000000000000000 AND
SUBSTR(DIGITS(SI.DATE_STAT),5,2) BETWEEN '01' AND '12' AND
SUBSTR(DIGITS(SI.DATE_STAT),9,1) BETWEEN '0' AND '3' AND
INT(SUBSTR(DIGITS(SI.DATE_STAT),7,2)) BETWEEN 1 AND
DAY(DATE(CAST(19+INT(SI.DATE_STAT / 100000000000000000) AS CHAR(2)) ||
TRANSLATE('YE-MN-01', DIGITS(SI.DATE_STAT), 'xxYEMNDA')) + 1 MONTH - 1 DAY)
THEN TIMESTAMP(CAST(19+INT(SI.DATE_STAT / 100000000000000000) AS CHAR(2)) ||
TRANSLATE('YE-MN-DA HR:UT:SC', DIGITS(SI.DATE_STAT),'xxYEMNDAxHRUTSC')) -
INT(MOD(3 - INT(SUBSTR(DIGITS(SI.DATE_STAT),9,1)),3)) DAYS +
INT(MOD(INT(SUBSTR(DIGITS(SI.DATE_STAT),16,2)) - 1,25) + 1) HOURS +
INT(MOD(4 - ((INT(SUBSTR(DIGITS(SI.DATE_STAT),16,2)) - 1) / 25),4) * 15)
MINUTES ELSE CAST(NULL AS TIMESTAMP)END)
FROM EXPORT.STAT_ITEM SI
WHERE (SI.INVOICE_REF = SH.SHPMNT_REF) AND SI.STAT_CODE = 'ABC') AS ABC,
(SELECT MIN(CASE WHEN SI.DATE_STAT >= 78000000000000000 AND
SUBSTR(DIGITS(SI.DATE_STAT),5,2) BETWEEN '01' AND '12' AND
SUBSTR(DIGITS(SI.DATE_STAT),9,1) BETWEEN '0' AND '3' AND
INT(SUBSTR(DIGITS(SI.DATE_STAT),7,2)) BETWEEN 1 AND
DAY(DATE(CAST(19+INT(SI.DATE_STAT / 100000000000000000) AS CHAR(2)) ||
TRANSLATE('YE-MN-01', DIGITS(SI.DATE_STAT), 'xxYEMNDA')) + 1 MONTH - 1 DAY)
THEN TIMESTAMP(CAST(19+INT(SI.DATE_STAT / 100000000000000000) AS CHAR(2)) ||
TRANSLATE('YE-MN-DA HR:UT:SC', DIGITS(SI.DATE_STAT),'xxYEMNDAxHRUTSC')) -
INT(MOD(3 - INT(SUBSTR(DIGITS(SI.DATE_STAT),9,1)),3)) DAYS +
INT(MOD(INT(SUBSTR(DIGITS(SI.DATE_STAT),16,2)) - 1,25) + 1) HOURS +
INT(MOD(4 - ((INT(SUBSTR(DIGITS(SI.DATE_STAT),16,2)) - 1) / 25),4) * 15)
MINUTES ELSE CAST(NULL AS TIMESTAMP)END)
FROM EXPORT.STAT_ITEM SI
WHERE (SI.INVOICE_REF = SH.SHPMNT_REF) AND SI.STAT_CODE = 'DEF') AS DEF,
//This should be wrong and I'm getting error.
coalesce((days(DEF) - days(ABC)),'0') as TotalTransitTime
What I wan is to show the date betweeen "DEF" and "ABC" and the default will be 0 if DEF or ABC is missing. Please help. Thanks a lot!

Calculate and Display Total Experience Months in YY/MM format in Sql Server

Consider the following code.
create table #temp (Min_Expr_InMonths int, Max_Expr_InMonths int)
insert into #temp values (40, 98)
insert into #temp values (null, null)
insert into #temp values (0, 0)
insert into #temp values (133, 145)
select ' (Exp - ' +
Convert(varchar, Case when j.Min_Expr_InMonths/12 < 10 then '0' + convert(varchar, j.Min_Expr_InMonths/12) else j.Min_Expr_InMonths/12 end) + '/' +
Convert(varchar,
case when j.Min_Expr_InMonths - ((j.Min_Expr_InMonths/12)*12) < 10 then '0' + convert(varchar, j.Min_Expr_InMonths - ((j.Min_Expr_InMonths/12)*12)) else
j.Min_Expr_InMonths - ((j.Min_Expr_InMonths/12)*12) end) + ' to ' + Convert(varchar,
Case when j.Max_Expr_InMonths/12 < 10 then '0' + convert(varchar, j.Max_Expr_InMonths/12) else j.Max_Expr_InMonths/12 end) + '/' +
Convert(varchar,
case when j.Max_Expr_InMonths - ((j.Max_Expr_InMonths/12)*12) < 10 then '0' + convert(varchar, j.Max_Expr_InMonths - ((j.Max_Expr_InMonths/12)*12)) else
j.Max_Expr_InMonths - ((j.Max_Expr_InMonths/12)*12) end) + ')' from #temp j
Output of the above query is as follows.
YY/MM
(Exp - 3/4 to 8/2)
NULL
(Exp - 0/0 to 0/0)
(Exp - 11/1 to 12/1)
What I wanted to achieve is as follows.
YY/MM
(Exp - 03/04 to 08/02)
(Exp - 00/00 to 00/00)
(Exp - 00/00 to 00/00)
(Exp - 11/01 to 12/01)
Is there a simpler way to achieve this, my query looks very untidy and difficult to read, also I am not sure about the performance as the DB rows increase.
Please Try below simplest query:
select 'Exp - ' +
right('00' + convert(varchar(2),coalesce(Min_Expr_InMonths,0)/12),2) + '/' +
right('00' + convert(varchar(2),coalesce(Min_Expr_InMonths,0)%12),2) + ' to '+
right('00' + convert(varchar(2),coalesce(Max_Expr_InMonths,0)/12),2) + '/' +
right('00' + convert(varchar(2),coalesce(Max_Expr_InMonths,0)%12),2) as 'YY/MM'
from #temp
Corrected select query:
SELECT '(Exp - ' +
CASE
WHEN j.Min_Expr_InMonths IS NULL
THEN '00'
WHEN (j.Min_Expr_InMonths/12 >= 10)
THEN CONVERT(VARCHAR, j.Min_Expr_InMonths/12)
ELSE
CONCAT('0',CONVERT(VARCHAR, j.Min_Expr_InMonths/12))
END
+ '/' +
CASE
WHEN j.Min_Expr_InMonths IS NULL
THEN '00'
WHEN j.Min_Expr_InMonths - ((j.Min_Expr_InMonths/12)*12) >= 10
THEN CONVERT(VARCHAR,j.Min_Expr_InMonths - ((j.Min_Expr_InMonths/12)*12))
ELSE
CONCAT('0',CONVERT(VARCHAR, j.Min_Expr_InMonths - ((j.Min_Expr_InMonths/12)*12)))
END
+ ' to ' +
CASE
WHEN j.Max_Expr_InMonths IS NULL
THEN '00'
WHEN j.Max_Expr_InMonths/12 >= 10
THEN CONVERT(VARCHAR, j.Max_Expr_InMonths/12)
ELSE
CONCAT('0',j.Max_Expr_InMonths/12)
END
+ '/' +
CASE
WHEN j.Max_Expr_InMonths IS NULL
THEN '00'
WHEN j.Max_Expr_InMonths - ((j.Max_Expr_InMonths/12)*12) >= 10
THEN CONVERT(VARCHAR, j.Max_Expr_InMonths - ((j.Max_Expr_InMonths/12)*12))
ELSE
CONCAT('0',CONVERT(VARCHAR,j.Max_Expr_InMonths - ((j.Max_Expr_InMonths/12)*12)))
END
+ ')'
FROM #temp j
OUTPUT
(Exp - 03/04 to 08/02)
(Exp - 00/00 to 00/00)
(Exp - 00/00 to 00/00)
(Exp - 11/01 to 12/01)
For Demo Follow the link:
http://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=d462f3f8cc4b945e01a7d594b016a105

Convert Decimal to Date in DB2

I have a column in my table having date value as Decimal like 20180715 for the date 15-07-2018.
I want to convert it to MMDDYYYY format.
Example:
Given decimal value 20180715 is converted to 07152018.
How to do it ?
try somthing like this:
select
VARCHAR_FORMAT( TIMESTAMP_FORMAT(cast(yourcolumn as varchar(8)), 'YYYYMMDD') , 'MMDDYYYY')
from yourtable
but you you want a really date do it:
select
DATE( TIMESTAMP_FORMAT(cast(yourcolumn as varchar(8)), 'YYYYMMDD'))
from yourtable
Try this query for the date
select
date(timestamp_format(char(yourcolumn+19000000), 'YYYYMMDD'))
from yourtable
To get the time
select
cast( substr( right( '00' || yourcolumn, 6) ,1,2) || ':' || substr( right( '00' || yourcolumn, 6) ,3,2) || ':' || substr( right( '00' || yourcolumn, 6) ,5,2) as time)
from yourtable