Redshift Error when adding date to a time stamp using case statement - case

I am trying to have a CASE statement that adds days to a time stamp column.
select cust_id,
case when type = 'a' then (created_date - INTERVAL '7 DAY')
when type = 'b' then (created_date - INTERVAL '10 DAY')
else 0 end as date_when_breach
from table
The above throws an error
Reason:
SQL Error [42804]: ERROR: CASE types integer and timestamp without time zone cannot be matched
Sample created_date value is 2019-02-14 11:16:16

Your CASE statement is not consistent with return types - first two branches return a DATE and the ELSE returns an INTEGER. Change your ELSE to return DATE (eg.current_date, depends on what you want to achieve) or NULL (or just remove it, which will have the same effect).
select
cust_id,
case
when type = 'a' then (created_date - INTERVAL '7 DAY')
when type = 'b' then (created_date - INTERVAL '10 DAY')
else NULL
end as date_when_breach
from table

Related

DB2 Date Cast Error for Parameter Position 1

Attempting to cast a string (formatted as YYYY-MM-DD) as ISO date. It's already in the right format but it is erroring out.
SELECT
*
FROM TABLE1
WHERE CHAR(VARCHAR((SUBSTRING(PARAMETER_VALUE,8,4)||
CASE SUBSTRING(PARAMETER_VALUE,4,3)
WHEN 'Jan' THEN '-01-'
WHEN 'Feb' THEN '-02-'
WHEN 'Mar' THEN '-03-'
WHEN 'Apr' THEN '-04-'
WHEN 'May' THEN '-05-'
WHEN 'Jun' THEN '-06-'
WHEN 'Jul' THEN '-07-'
WHEN 'Aug' THEN '-08-'
WHEN 'Sep' THEN '-09-'
WHEN 'Oct' THEN '-10-'
WHEN 'Nov' THEN '-11-'
WHEN 'Dec' THEN '-12-' END||
SUBSTRING(PARAMETER_VALUE,1,2))
),ISO) > CURRENT DATE;
I receive the following error: The statement was not processed because the data type, length or value of the argument for the parameter in position "1" of routine "SYSIBM.CHAR" is incorrect. Parameter name: "".. SQLCODE=-171, SQLSTATE=42815, DRIVER=4.19.56
I am using IBM Data Studio to run this.
PARAMETER_VALUE looks like it's DDMonYYYY if you wanted to use TO_DATE similar to:
SELECT
*
FROM TABLE1
WHERE TO_DATE(PARAMETER_VALUE, 'DDMonYYYY') > CURRENT DATE;
If that's not the correct format of that column then you can put together the correct string from here: https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.5.0/com.ibm.db2.luw.sql.ref.doc/doc/r0007107.html

Carry Forward values in Presto

I am using the below query to pivot my data and generate a CSV but the problem is I have a dataset in which the data points are coming in a scattered way with each timestamp.
with map_date as (
SELECT
vin,
epoch,
timestamp,
date,
map_agg(signalName, value) as map_values
from hive.vehicle_signals.vehicle_signals_flat
where date(date) = date('2020-03-12')
and date(cast(from_unixtime(epoch) as timestamp) - interval '0' hour) = current_date - interval '2' day
and vin = '000011'
and signalName in ('timestamp','epoch','msgId','usec','vlan','vin','msgName','value')
GROUP BY vin, epoch, timestamp, date
order by timestamp desc
)
SELECT
epoch
, timestamp
, CASE WHEN element_at(map_values, 'value') IS NOT NULL THEN map_values['value'] ELSE NULL END AS value
, vin
, current_date - interval '2' day AS date
from map_date
I get the following CSV as a result. Is there a way I can carry forward the value until a new value is found at a newer timestamp? Like in the image below the value '14.3' comes and the next value '16.5' comes after a few timestamps, How can I carry the value '14.3' till row 7th and repeat the logic on the entire column. How can I make my output field look like column 'G' in the image using Presto?
Thanks in advance!!
You can use a mysql #variable to store the last value, for example:
SELECT
epoch
, timestamp
, CASE WHEN element_at(map_values, 'value') IS NOT NULL THEN #last_value:= map_values['value'] ELSE #last_value END AS value
, vin
, current_date - interval '2' day AS date
from map_date, (select #last_value:=0) v
The last part, (select #last_value:=0) v is to initialize the #last_value variable.
A basic tutorial
https://www.mysqltutorial.org/mysql-variables/
More advanced tutorial with additional info
https://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/

SQL: Sum based on specified dates

Thanks again for the help everyone. I went with the script below...
SELECT beginning, end,
(SELECT SUM(sale) FROM sales_log WHERE date BETWEEN beginning AND `end` ) AS sales
FROM performance
and I added a salesperson column to both the performance table and sales_log but it winds up crashing DB Browser. What is the issue here? New code below:
SELECT beginning, end, salesperson
(SELECT SUM(sale) FROM sales_log WHERE (date BETWEEN beginning AND end) AND sales_log.salesperson = performance.salesperson ) AS sales
FROM performance
I believe that the following may do what you wish or be the basis for what you wish.
WITH sales_log_cte AS
(
SELECT substr(date,(length(date) -3),4)||'-'||
CASE WHEN length(replace(substr(date,instr(date,'/')+1,2),'/','')) < 2 THEN '0' ELSE '' END
||replace(substr(date,instr(date,'/')+1,2),'/','')||'-'||
CASE WHEN length(substr(date,1,instr(date,'/') -1)) < 2 THEN '0' ELSE '' END||substr(date,1,instr(date,'/') -1) AS date,
CAST(sale AS REAL) AS sale
FROM sales_log
),
performance_cte AS
(
SELECT substr(beginning,(length(beginning) -3),4)||'-'||
CASE WHEN length(replace(substr(beginning,instr(beginning,'/')+1,2),'/','')) < 2 THEN '0' ELSE '' END
||replace(substr(beginning,instr(beginning,'/')+1,2),'/','')||'-'||
CASE WHEN length(substr(beginning,1,instr(beginning,'/') -1)) < 2 THEN '0' ELSE '' END||substr(beginning,1,instr(beginning,'/') -1)
AS beginning,
substr(`end`,(length(`end`) -3),4)||'-'||
CASE WHEN length(replace(substr(`end`,instr(`end`,'/')+1,2),'/','')) < 2 THEN '0' ELSE '' END
||replace(substr(`end`,instr(`end`,'/')+1,2),'/','')||'-'||
CASE WHEN length(substr(`end`,1,instr(`end`,'/') -1)) < 2 THEN '0' ELSE '' END||substr(`end`,1,instr(`end`,'/') -1)
AS `end`
FROM performance
)
SELECT beginning, `end` , (SELECT SUM(sale) FROM sales_log_cte WHERE date BETWEEN beginning AND `end` ) AS sales
FROM performance_cte
;
From your data this results in :-
As can be seen the bulk of the code is converting the dates into a format (i.e. YYYY-MM-DD) that is usable/recognisable by SQLite for the BETWEEN clause.
Date And Time Functions
I don't believe that you want a join between performance (preformance_cte after reformatting the dates) and sales_log (sales_log_cte) as this will be a cartesian product and then sum will sum all the results within the range.
The use of end as a column name is also awkward as it is a KEYWORD requiring it to be enclosed (` grave accents used in the above).
The above works by using 2 CTE's (Common Table Expresssions), which are temporary tables who'd life time is for the query in which they are used.
The first sales_log_cte is simply the sales_log table but with the date reformatted. The second, likewise, is simply the performace table with the dates reformatted.
If the tables already has suitable date formatting then all of the above could simply be :-
SELECT beginning, `end` , (SELECT SUM(sale) FROM sales_log WHERE date BETWEEN beginning AND `end` ) AS sales FROM performance;

Oracle to_date return incorrect result

I have a table 4 columns - Code, Status, EffectiveDate (EFF_DT), EndDate (END_DT). All the columns are Varchar2 type. EFF_DT and END_DT has ISO format date (YYYY-MM-DD) with NULL values for few rows. Need to get the rows which has END_DT greater than today's date.
While executing the below query, it returns all the Not NULL rows for END_DT. Do not compare the END_DT at all.
select code, status, EFF_DT, END_DT
from (
select CODE, EFF_DT, Status,to_date("END_DT" ,'YYYY-MM-DD' ) as END_DT
from xxx.ZZZ
) TAB
where to_date(TAB.END_DT ,'DD-MM-YY' ) > to_date(CAST(CURRENT_TIMESTAMP as Date), 'DD-MM-YY')
ORDER BY 1 ASC
But the below query compares the END_DT and returns the result properly -
SELECT "TAB"."CODE" , "TAB"."STATUS" AS "STATUS" , "TAB"."EFF_DT" , "TAB"."END_DT"
FROM xxx.ZZZ "TAB"
WHERE ( (to_date("TAB"."END_DT",'YYYY-MM-DD') > to_date(CAST(CURRENT_TIMESTAMP as Date), 'YY-MM-DD')) )
ORDER BY 1 ASC
What is going wrong with the 1st query?
I see difference in return value of END_DT.
For the 1st query, the data is coming like -
while as for the 2nd query, the data is coming like

AgeCalendar Datetime Field Issue

For my AgingCalendar field, I have 3 conditions using CASE WHEN:
CASE WHEN A.[END_DTTM] > A.[STRT_DTTM] THEN C2.[DY_OF_CAL_NUM] - C1.[DY_OF_CAL_NUM]
WHEN A.[END_DTTM] IS NULL and A.[STRT_DTTM] IS NOT NULL THEN C3.[DY_OF_CAL_NUM] - C1.[DY_OF_CAL_NUM]
WHEN A.[END_DTTM] = A.[STRT_DTTM] THEN 1
END AS AgeCalendar
For my third condition, I'm trying to basically say when the End Datetime = Start Datetime, the age in Calendar days should be set to 1 calendar day.
However, in some of the records I'm bringing in, the start date equals the end date, but the times associated with each datetime are different. When this happens, those records are receiving a NULL in the AgeCalendar field.(For example I could have 6/6/2014 0:00:00 = 6/6/2014 0:00:00, and that will give me 1...but if I had 6/6/2014 0:00:00 = 6/6/2014 0:03:59 (or something like that)...it'll give me a NULL value because it's not matching.
How can I update the code above so that I'm basically saying when End Date = Start Date, then 1...regardless of not having matching times?
CASTor CONVERT them as dates to ignore the time.
WHEN CONVERT(DATE, A.[END_DTTM]) = CONVERT(DATE, A.[STRT_DTTM]) THEN 1
OR
WHEN CAST(A.[END_DTTM] AS DATE) = CAST(A.[STRT_DTTM] AS DATE) THEN 1

Resources