Teradata date subtract issue in PERIOD column - teradata

I have a teradata table ABC . I have a column in the table which is of PERIOD data type ( Name of the column is ef_dtm) . I need to update the starting bound of the period column(subtract it by 1 day) whenever starting bound of the period column is '12/31/9999'.
I am using the below query . But it is saying
INVALID Interval Literal.
Can you suggest me an update query?
Nonsequenced validtime
update ABC
set ef_dtm = PERIOD(CAST(end(ef_dtm) as Date) -INTERVAL '-1' DAY , end(ef_dtm))
where begin(ef_dtm) = '12/31/9999'

The error is because of part INTERVAL '-1' DAY
It should be INTERVAL -'1' DAY i.e. minus - outside the '1'
Your query has 2 more problems.
No need to cast period begin to DATE as INTERVAL arithmetic works on TIMESTAMP
DATE literals are wrong. It should be YYYY-MM-DD; Moreover it should be TIMESTAMP corresponding to period column datatype.
Correct query is as below.
nonsequenced validtime
UPDATE ABC
SET ef_dtm = PERIOD(begin(ef_dtm) + INTERVAL -'1' DAY, end(ef_dtm))
WHERE begin(ef_dtm) = TIMESTAMP '1999-12-31 00:00:00.000000';
OR
nonsequenced validtime
UPDATE ABC
SET ef_dtm = PERIOD(begin(ef_dtm) - INTERVAL '1' DAY, end(ef_dtm))
WHERE begin(ef_dtm) = TIMESTAMP '1999-12-31 00:00:00.000000';
DEMO
Create Table:
CREATE TABLE ABC ( ef_dtm period(timestamp(6)) AS validtime ) NO PRIMARY INDEX;
Insert Data:
INSERT INTO abc(period (TIMESTAMP '1999-12-31 00:00:00.000000', TIMESTAMP '1999-12-31 23:59:00.000000'));
After select
ef_dtm
------------------------------------------------------------
('1999-12-31 00:00:00.000000', '1999-12-31 23:59:00.000000')
Update Data:
nonsequenced validtime
UPDATE ABC
SET ef_dtm = PERIOD(begin(ef_dtm) + INTERVAL -'1' DAY, end(ef_dtm))
WHERE begin(ef_dtm) = TIMESTAMP '1999-12-31 00:00:00.000000';
After SELECT
ef_dtm
------------------------------------------------------------
('1999-12-30 00:00:00.000000', '1999-12-31 23:59:00.000000')

Related

Get the MAX(value) using fiscal type years ie; 2016/2017, etc

My calendar year runs from 07-01-(of one year) to 06-30-(of the next year).
My SQLITE DB has a Timestamp column and it's data type is datetime and stores the timestamp as 2023-09-01 00:00:00.
What I'm trying to do is get the MAX date of the latest snowfall. For example, with my seasonal years beginning July-01 (earliest) and ending June 30 (latest), I want to find only the latest (MAX) date snowfall was recorded, regardless of the year, based on the month.
Say if out of five years (2017 to 2022) worth of data in the database and it snowed Mar 15, 2020. And there was no date greater than than this one in any year, then this would be the latest date regardless which year it fell.
I've been trying many variations of the below query. This query says it runs with no mistakes and returns "null" values. I'm using SQLITE DB Browser to write and test the query.
SELECT Timestamp, MAX(strftime('%m-%d-%Y', Timestamp)) AS lastDate,
snowDepth AS lastDepth FROM DiaryData
WHERE lastDepth <> 0 BETWEEN strftime('%Y-%m-%d', Timestamp,'start of year', '+7 months')
AND strftime('%Y-%m-%d', Timestamp, 'start of year', '+1 year', '+7 months', '- 1 day')
ORDER BY lastDate LIMIT 1
and this is what's in my test database:
Timestamp snowFalling snowLaying snowDepth
2021-11-10 00:00:00 0 0 7.2
2022-09-15 00:00:00 0 0 9.5
2022-12-01 00:00:00 1 0 2.15
2022-10-13 00:00:00 1 0 0.0
2022-05-19 00:00:00 0 0 8.82
2023-01-11 00:00:00 0 0 3.77
If it's running properly I should expect:
Timestamp
lastDate
lastDepth
2022-05-19 00:00:00
05-19-2022
8.82
What am I missing or is this not possible in SQLITE? Any help would be appreciative.
Use aggregation by fiscal year utilizing SQLite's feature of bare columns:
SELECT Timestamp,
strftime('%m-%d-%Y', MAX(Timestamp)) AS lastDate,
snowDepth AS lastDepth
FROM DiaryData
WHERE snowDepth <> 0
GROUP BY strftime('%Y', Timestamp, '+6 months');
See the demo.
I'd get season for each record first, snowfall date relative to record's season start date after this, and largest snowfall date relative to record's season start date finally:
with
data as (
select
*
, case
when cast(strftime('%m', "Timestamp") as int) <= 7
then strftime('%Y-%m-%d', "Timestamp", 'start of year', '-1 year', '+6 months')
else strftime('%Y-%m-%d', "Timestamp", 'start of year', '+6 months')
end as "Season start date"
from DiaryData
where 1==1
and "snowDepth" <> 0.0
)
, data2 as (
select
*
, julianday("Timestamp") - julianday("Season start date")
as "Showfall date relative to season start date"
from data
)
, data3 as (
select
"Timestamp"
, "snowFalling"
, "snowLaying"
, "snowDepth"
from data2
group by null
having max("Showfall date relative to season start date")
)
select
*
from data3
demo
You can use the ROW_NUMBER window function to address this problem, yet need to apply a subtle tweak. In order to account for fiscal years, you can partition on the year for timestamps slided 6 months further. In this way, ranges like [2021-01-01, 2021-12-31] will instead be slided to [2021-06-01, 2022-05-31].
WITH cte AS (
SELECT *, ROW_NUMBER() OVER(
PARTITION BY STRFTIME('%Y', DATE(Timestamp_, '+6 months'))
ORDER BY Timestamp_ DESC ) AS rn
FROM tab
)
SELECT Timestamp_,
STRFTIME('%d-%m-%Y', Timestamp_) AS lastDate,
snowDepth AS lastDepth
FROM cte
WHERE rn = 1
Check the demo here.

SQLite last 24h query with 2 rows date and time

I want to query last 24h in my database SQLite. I have 2 rows time example (18:04:56) and date (2020-12-06 ). When I use this query
SELECT name,cdate,ctime, * FROM {table} WHERE cdate >= datetime('now','-1 day') ORDER BY id DESC
I got only last queries in the same day. (LAST QUERY 00:00:46)
How deal with it ?
You should create a datetime value from cdate and ctime to compare with DATETIME('now','-1 day'):
SELECT name, cdate, ctime
FROM {table}
WHERE (cdate || ' ' || ctime) >= DATETIME('now','-1 day')
ORDER BY id DESC

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/

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

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

Not able to filter records based on date filter in Informix

I want to put filter on an Informix query:
WHERE agentstatedetail.eventdatetime < '1753-01-01 00:00:00' - INTERVAL(3) DAY TO DAY
but it fails ...
Please tell where it goes wrong.
As noted in a comment, the solution is to ensure that the string is interpreted as a DATETIME value. The simple way to do that is to use the DATETIME literal notation:
DATETIME(1753-01-01 00:00:00) YEAR TO SECOND
To demonstrate:
CREATE TABLE agentstatedetail
(
eventdatetime DATETIME YEAR TO SECOND NOT NULL PRIMARY KEY,
eventname VARCHAR(64) NOT NULL
);
INSERT INTO agentstatedetail VALUES('1752-12-25 12:00:00', 'Christmas Day, Noon, 1752');
INSERT INTO agentstatedetail VALUES('1752-12-31 12:00:00', 'New Year''s Eve, Noon, 1752');
INSERT INTO agentstatedetail VALUES('1753-01-01 12:00:00', 'New Year''s Day, Noon, 1753');
SELECT * FROM agentstatedetail WHERE agentstatedetail.eventdatetime < '1753-01-01 00:00:00' - INTERVAL(3) DAY TO DAY;
This is your original WHERE clause embedded into a minimal SELECT statement. It yields the error:
SQL -1261: Too many digits in the first field of datetime or interval.
(NB: It would have been helpful to include the error message in the question.)
Here's an alternative version of the query, with the DATETIME literal in place:
SELECT * FROM agentstatedetail
WHERE agentstatedetail.eventdatetime < DATETIME(1753-01-01 00:00:00) YEAR TO SECOND -
INTERVAL(3) DAY TO DAY
;
Output from the sample data:
1752-12-25 12:00:00|Christmas DAY, Noon, 1752
I observe that the value calculated is a constant; you could rewrite the code as:
SELECT * FROM agentstatedetail
WHERE agentstatedetail.eventdatetime < DATETIME(1752-12-29 00:00:00) YEAR TO SECOND
I suspect that the value is passed as a parameter somewhere along the line.
Alternatively, you can cast the string to a DATETIME value and you'd get the same result:
SELECT * FROM agentstatedetail
WHERE agentstatedetail.eventdatetime < CAST('1753-01-01 00:00:00' AS DATETIME YEAR TO SECOND) -
INTERVAL(3) DAY TO DAY
;
or:
SELECT * FROM agentstatedetail
WHERE agentstatedetail.eventdatetime < '1753-01-01 00:00:00'::DATETIME YEAR TO SECOND -
INTERVAL(3) DAY TO DAY

Resources