Where Clause on two column sequentially - sql

I want to select query where I can fetch records from a table based 2 column where timestamp value match in both column sequentially.
SELECT *
FROM commerce_order
WHERE CHANGED BETWEEN 1638342000 AND 1641020400
AND created BETWEEN 1638342000 AND 1641020400
Like column changed update 31st at 10 AM and Column created have value 31 at 11AM both should be shown in the result 1 10 AM then next in 11 PM
10 AM
11 AM

So the "created" timestamp should be 1 minute after the "changed" timestamp?
Then you could truncate them on the minute to compare them.
select *
from commerce_order
where changed between unix_timestamp('2021-12-01 07:00') and unix_timestamp('2022-01-01 07:00')
and cast(date_format(from_unixtime(created), '%Y-%m-%d %H:%i') AS datetime) = cast(date_format(from_unixtime(changed), '%Y-%m-%d %H:%i') AS datetime) + interval 1 minute
db<>fiddle here

Related

Back-filling time-series data with previous time's values

I have a table of time-series data that has some gaps in the series. An example of the data is below:
Date
Value
2022-11-17
1
2022-11-14
2
I want to insert rows for the dates between the existing rows (2022-11-15, 2022-11-16) that have the value of the latest date before the date being inserted (the 2022-11-14 row).
I started by using an imperative solution in my application programming language but I'm convinced there must be a way to do this in SQL.
demo:db<>fiddle
INSERT INTO mytable -- 5
SELECT
generate_series( -- 1
mydate + 1, -- 2
lead(mydate) OVER (ORDER BY mydate) - 1, -- 3
interval '1 day'
)::date as gs,
t.myvalue -- 4
FROM mytable t;
Use generate_series() to generate date series
Start of your date series is the next day of the row's date value
End of your date series is the day before the next row's date value. Here the lead() window function is used to access the next row
Use the generated dates from the function and the value of the actual row for the newly generated rows.
Finally insert them into your table.

How do I add number of days from original dates in new column

Hopefully a quick one on BigQuery
I've tried intervals and days but can't quite seem to get what I want. For date row on the example table below I want and adjacent row in a new column that just adds 42 days to the original date and time (time is always 00:00:00 if that helps).
Desired output below:
original_datetime
date_time_plus_42_days
2016-04-01T00:00:00
plus 42 days to left column
2016-05-04T00:00:00
plus 42 days to left column
2018-05-17T00:00:00
plus 42 days to left column
2019-09-01T00:00:00
plus 42 days to left column
2016-04-01T00:00:00
plus 42 days to left column
Consider also below approach with explicit use of interval data type
select original_datetime,
original_datetime + interval 42 day as date_time_plus_42_days
from your_table
if applied to sample data in your question
with your_table as (
select datetime '2016-04-01T00:00:00' original_datetime union all
select '2016-05-04T00:00:00' union all
select '2018-05-17T00:00:00' union all
select '2019-09-01T00:00:00' union all
select '2016-04-01T00:00:00'
)
output is
Benefit of using interval data type is that in one shot you can add multiple units - for example not just days but also hours as in example below
select original_datetime,
original_datetime + make_interval(day => 42, hour => 5) as date_time_plus_42_days
from your_table
with output
The function you are looking for is called: DATETIME_ADD. It is documented here.
For instance:
WITH table AS (
SELECT DATETIME("2016-04-01T00:00:00") AS datetime)
SELECT
datetime,
DATETIME_ADD(datetime, INTERVAL 42 DAY) as datetime_plus_42
FROM table;

How do you filter to get data that is in between a certain time of day in IBM DB2

I am trying to add a filter condition in the DB2 database. I am new to it and come from an Oracle background. I am trying to get records with dates in between today at 4 AM and today at 5 PM only. I currently have the below query that returns zero results:
db2 => select datetimeColumn from datetimeExample WHERE datetimeColumn BETWEEN timestamp(current date) - 1 day + 4 hour AND timestamp(current date) - 1 day + 13 hour
DATETIMECOLUMN
--------------------------
0 record(s) selected.
And here is the data in the table that I believe should show but there is something wrong with condition statement, any help is appreciated
db2 => select * from datetimeExample
DATETIMECOLUMN
--------------------------
2016-06-16-09.38.53.759000
1988-12-25-17.12.30.000000
2016-12-25-17.10.30.000000
2016-06-16-04.10.30.000000
2016-06-16-05.10.30.000000
1988-12-25-15.12.30.000000
1988-12-25-14.12.30.000000
2016-06-16-12.10.30.000000
2016-06-16-07.10.30.000000
2016-06-16-08.10.30.000000
10 record(s) selected.
The query should work when you leave out the - 1 day. The reason is that timestamp(current date) returns the timestamp for today at zero hours. Then you add 4 hours and are at the required start time. Similar maths for the end time (and 5 pm should be + 17 hours).
select datetimeColumn from datetimeExample
WHERE datetimeColumn
BETWEEN timestamp(current date) + 4 hours AND timestamp(current date) + 17 hours

Netezza get records last updated in last 5 minutes using a last modified time stamp column in the table?

How to select records that updated in last 5 minutes using a last_modified_timestamp column in the table using current_date or current_timestamp function in Netezza?
If you've installed the SQL extensions, then you can use minutes_between.
select
*
from
table
where
minutes_between(current_timestamp, last_modified_timestamp) < 5
If not, you can always use intervals.
select
*
from
table
where
last_modified_timestamp > current_timestamp - '5 minute'::interval

How to find first free time in reservations table in PostgreSql

Reservation table contains reservations start dates, start hours and durations.
Start hour is by half hour increments in working hours 8:00 .. 18:00 in work days.
Duration is also by half hour increments in day.
CREATE TABLE reservation (
startdate date not null, -- start date
starthour numeric(4,1) not null , -- start hour 8 8.5 9 9.5 .. 16.5 17 17.5
duration Numeric(3,1) not null, -- duration by hours 0.5 1 1.5 .. 9 9.5 10
primary key (startdate, starthour)
);
table structure can changed if required.
How to find first free half hour in table which is not reserved ?
E.q if table contains
startdate starthour duration
14 9 1 -- ends at 9:59
14 10 1.5 -- ends at 11:29, e.q there is 30 minute gap before next
14 12 2
14 16 2.5
result should be:
starthour duration
11.5 0.5
Probably PostgreSql 9.2 window function should used to find
first row whose starthour is greater than previous row starthour + duration
How to write select statement which returns this information ?
Postgres 9.2 has range type and I would recommend to use them.
create table reservation (reservation tsrange);
insert into reservation values
('[2012-11-14 09:00:00,2012-11-14 10:00:00)'),
('[2012-11-14 10:00:00,2012-11-14 11:30:00)'),
('[2012-11-14 12:00:00,2012-11-14 14:00:00)'),
('[2012-11-14 16:00:00,2012-11-14 18:30:00)');
ALTER TABLE reservation ADD EXCLUDE USING gist (reservation WITH &&);
"EXCLUDE USING gist" creates index which disallows to inset overlapping entries. You can use the following query to find gaps (variant of vyegorov's query):
with gaps as (
select
upper(reservation) as start,
lead(lower(reservation),1,upper(reservation)) over (ORDER BY reservation) - upper(reservation) as gap
from (
select *
from reservation
union all values
('[2012-11-14 00:00:00, 2012-11-14 08:00:00)'::tsrange),
('[2012-11-14 18:00:00, 2012-11-15 00:00:00)'::tsrange)
) as x
)
select * from gaps where gap > '0'::interval;
'union all values' masks out non working times hence you can make reservation between 8am and 18pm only.
Here is the result:
start | gap
---------------------+----------
2012-11-14 08:00:00 | 01:00:00
2012-11-14 11:30:00 | 00:30:00
2012-11-14 14:00:00 | 02:00:00
Documentation links:
- http://www.postgresql.org/docs/9.2/static/rangetypes.html "Range Types"
- https://wiki.postgresql.org/images/7/73/Range-types-pgopen-2012.pdf
Maybe not the best query, but it does what you want:
WITH
times AS (
SELECT startdate sdate,
startdate + (floor(starthour)||'h '||
((starthour-floor(starthour))*60)||'min')::interval shour,
startdate + (floor(starthour)||'h '||
((starthour-floor(starthour))*60)||'min')::interval
+ (floor(duration)||'h '||
((duration-floor(duration))*60)||'min')::interval ehour
FROM reservation),
gaps AS (
SELECT sdate,shour,ehour,lead(shour,1,ehour)
OVER (PARTITION BY sdate ORDER BY shour) - ehour as gap
FROM times)
SELECT * FROM gaps WHERE gap > '0'::interval;
Some notes:
It will be better not to separate time and data of the event. If you have to, then use standard types;
If it is not possible to go with standard types, create function to convert numeric hours into the time format.