Sum all values in a column and group by 2 minutes - sql

I want to sum all values in a column "value" and group by a interval of 2 minutes
I have values like this:
value TIME
0.3 2019-05-22 01:11:45---> first value 0,3
0.3 2019-05-22 01:12:16-----|
0.3 2019-05-22 01:13:26-----|second value 0,6
0.2 2019-05-22 01:13:56---|
0.4 2019-05-22 01:14:06---|
0.6 2019-05-22 01:15:43 --|third value 1,2
But what I really want is like this:
value TIME
0.3 2019-05-22 01:11:45
0.6 2019-05-22 01:13:45
1.2 2019-05-22 01:15:45
My code in postgresql:
SELECT medi_sensor.value, time
FROM medi_sensor
JOIN sensor ON medi_sensor.sensor_name = sensor.name
JOIN mote ON num_mot=mot_id
JOIN room ON room_id=id_div
WHERE medi_sensor.sensor_name LIKE 'current%' AND room.name='DIV' AND time>'2019-05-22' AND time<'2019-05-24'
ORDER BY time ASC
The problem is how to group by minute to minute in my time column

In Postgres, you can use generate_series() to generate the values:
select gs.t, sum(value)
from (select ms.value, time, min(time) over () as min_time, max(time) over () as max_time
from medi_sensor ms join
sensor s
on ms.sensor_name = s.name join
mote
on num_mot = mot_id join
room r
on room_id = id_div
where ms.sensor_name LIKE 'current%' and
r.name = 'DIV' and
time > '2019-05-22' and
time < '2019-05-24'
) x right join lateral
generate_series(min_time, max_time, interval '2 minute') gs(t)
on time >= gs.t and time < ts.t + interval '2 minute'
order by gs.t;
I would recommend that you use table aliases for all column references in your query.
EDIT:
with x as (
select ms.value, time
from medi_sensor ms join
sensor s
on ms.sensor_name = s.name join
mote
on num_mot = mot_id join
room r
on room_id = id_div
where ms.sensor_name LIKE 'current%' and
r.name = 'DIV' and
time > '2019-05-22' and
time < '2019-05-24'
) x
select gs.ts, sum(x.value)
from (select generate_series(min_time, max_time, interval '2 minute') as ts
from (select min(time) as min_time, max(time) as max_time
from x
)
) gs left join
x
on x.time >= gs.t and x.time < ts.t + interval '2 minute'
group by gs.ts
order by gs.ts;

Related

How to subtract two timestamps in SQL and then count?

I want to basically find out how many users paid within 15 mins, 30 mins and 60 mins of my payment_time and trigger_time
I have the following query
with redshift_direct() as conn:
trigger_time_1 = pd.read_sql(f"""
with new_data as
(
select
cycle_end_date
, prime_tagging_by_issuer_and_product
, u.user_id
, settled_status
, delay,
ots_created_at + interval '5:30 hours' as payment_time
,case when to_char(cycle_end_date,'DD') = '15' then 'Odd' else 'Even' end as cycle_order
from
settlement_summary_from_snapshot s
left join (select distinct user_phone_number, user_id from user_events where event_name = 'UserCreatedEvent') u
on u.user_id = s.user_id
and cycle_type = 'end_cycle'
and cycle_end_date > '2021-11-30' and cycle_end_date < '2022-01-15'
)
select
bucket_id
, cycle_end_date, d.cycle_order
, date(cycle_end_date) as t_cycle_end_date
,d.prime_tagging_by_issuer_and_product
,source
,status as cause
,split_part(campaign_name ,'|', 1) as campaign
,split_part(campaign_name ,'|', 2) as sms_cycle_end_date
,split_part(campaign_name ,'|', 3) as day
,split_part(campaign_name ,'|', 4) as type
,to_char(to_date(split_part(campaign_name ,'|', 2) , 'DD/MM/YYYY'), 'YYYY-MM-DD') as campaign_date,
d.payment_time, payload_event_timestamp + interval '5:30 hours' as trigger_time
,count( s.user_id) as count
from sms_callback_events s
inner join new_data d
on s.user_id = d.user_id
where bucket_id > 'date_2021_11_30' and bucket_id < 'date_2022_01_15'
and campaign_name like '%RC%'
and event_name = 'SmsStatusUpdatedEvent'
group by 1,2,3,4,5,6,7,8,9,10,11,12,13,14
""",conn)
How do i achieve making 3 columns with number of users who paid within 15mins, 30 mins and 60 mins after trigger_time in this query? I was doing it with Pandas but I want to find a way to do it here itself. Can someone help?
I wrote my own DATEDIFF function, which returns an integer value of differencing between two dates, difference by day, by month, by year, by hour, by minute and etc. You can use this function on your queries.
DATEDIFF Function SQL Code on GitHub
Sample Query about using our DATEDIFF function:
select
datediff('minute', mm.start_date, mm.end_date) as diff_minute
from
(
select
'2022-02-24 09:00:00.100'::timestamp as start_date,
'2022-02-24 09:15:21.359'::timestamp as end_date
) mm;
Result:
---------------
diff_minute
---------------
15
---------------

H2 SQL Query column not found in scope

In relation with : SQL: Find unavailability per minute of a ressource in an appointment
((click above link for schema + info))
I'm trying to run this query in an H2 SQL database. I'm a little unfamiliar with H2 syntax. I noted the column num in the WHERE clause that causes the issue.
Error:
Column "NUM" not found; SQL statement:
CREATE FORCE VIEW (
SELECT
"A"."APPOINTMENT_ID",
"A"."APPOINTMENT_START_TIME",
"A"."APPOINTMENT_END_TIME",
"C"."COMPONENT_HOST_NAME",
'unavailable' AS "STATE"
FROM "PUBLIC"."APPOINTMENT" "A"
LEFT OUTER JOIN "PUBLIC"."APPOINTMENT_COMPONENT" "AC"
ON "A"."APPOINTMENT_ID" = "AC"."APPOINTMENT_ID"
INNER JOIN "PUBLIC"."COMPONENT" "C"
ON "C"."COMPONENT_ID" = "AC"."COMPONENT_ID"
WHERE ((CONVERT("A"."APPOINTMENT_START_TIME", TIME) <= DATEADD('minute', "NUM", CAST('00:00:00' AS TIME)))
AND (CONVERT("A"."APPOINTMENT_END_TIME", TIME) >= DATEADD('minute', "NUM", CAST('00:00:00' AS TIME))))
AND ("C"."COMPONENT_ID" IN(1))
FETCH FIRST ROW ONLY
) AS
SELECT
"A"."APPOINTMENT_ID",
"A"."APPOINTMENT_START_TIME",
"A"."APPOINTMENT_END_TIME",
"C"."COMPONENT_HOST_NAME",
'unavailable' AS "STATE"
FROM "PUBLIC"."APPOINTMENT" "A"
LEFT OUTER JOIN "PUBLIC"."APPOINTMENT_COMPONENT" "AC"
ON "A"."APPOINTMENT_ID" = "AC"."APPOINTMENT_ID"
INNER JOIN "PUBLIC"."COMPONENT" "C"
ON "C"."COMPONENT_ID" = "AC"."COMPONENT_ID"
WHERE ((CONVERT("A"."APPOINTMENT_START_TIME", TIME) <= DATEADD('minute', "NUM", CAST('00:00:00' AS TIME)))
AND (CONVERT("A"."APPOINTMENT_END_TIME", TIME) >= DATEADD('minute', "NUM", CAST('00:00:00' AS TIME))))
AND ("C"."COMPONENT_ID" IN(1))
FETCH FIRST ROW ONLY [42122-200] 42S22/42122 (Help)
My code:
with times(num) as
(
select 30 as num
union all select (num + 30)
from times where num < (24*60)
)
select dateadd('minute', num, cast('00:00:00' as time)) as datetimeinterval, unavailabilities.state from times
outer join(
select top 1 a.appointment_id, a.appointment_start_time, a.appointment_end_time, c.component_host_name, 'unavailable' as state
from appointment a
left join appointment_component ac on a.appointment_id = ac.appointment_id
inner join component c on c.component_id = ac.component_id
where
dateadd('minute', -->num<--, cast('00:00:00' as time)) between convert(a.appointment_start_time, time) and convert(a.appointment_end_time, time)
and
c.component_id in (1)
) unavailabilities
TLDR: Trying to get unavailabilities of a list of components by the minute or by a range of minutes (30 minutes here). Num should return a multiple of 30 in this case, depending on the time frame selected for which it will check if the components are taken or not.
N.B. I changed machine=component and appmach=appointment_component (cross table) from the link above
I am not sure about the syntax. I am not very much familiar with H2. But isn't num should be used in on clause instead of subquery ? Please check:
with recursive times(num) as
(
select 30 as num
union all select (num + 30)
from times where num < (24*60)
)
select dateadd('minute', num, cast('00:00:00' as time)) as datetimeinterval, unavailabilities.state from times
outer join(
select top 1 a.appointment_id, a.appointment_start_time, a.appointment_end_time, c.component_host_name, 'unavailable' as state
from appointment a
left join appointment_component ac on a.appointment_id = ac.appointment_id
inner join component c on c.component_id = ac.component_id
where
dateadd('minute', -->num<--, cast('00:00:00' as time)) between convert(a.appointment_start_time, time) and convert(a.appointment_end_time, time)
and
c.component_id in (1)
) unavailabilities
on dateadd('minute', num, cast('00:00:00' as time)) between convert(appointment_start_time, time) and convert(appointment_end_time, time)

Divide results from two query by another query in SQL

I have this query in Metabase:
with l1 as (SELECT date_trunc ('day', Ticket_Escalated_At) as time_scale, count (Ticket_ID) as chat_per_day
FROM CHAT_TICKETS where SUPPORT_QUEUE = 'transfer_investigations'
and date_trunc('month', TICKET_ESCALATED_AT) > now() - interval '6' Month
GROUP by 1)
with l2 as (SELECT date_trunc('day', created_date) as week, count(*) as TI_watchman_ticket
FROM jira_issues
WHERE issue_type NOT IN ('Transfer - General', 'TI - Advanced')
and date_trunc('month', created_date) > now() - interval '6' Month
and project_key = 'TI2'
GROUP BY 1)
SELECT l1.* from l1
UNION SELECT l2.* from l2
ORDER by 1
and this one:
with hours as (SELECT date_trunc('day', ws.start_time) as date_
,(ifnull(sum((case when ws.shift_position = 'TI - Non-watchman' then (minutes_between(ws.end_time, ws.start_time)/60) end)),0) + ifnull(sum((case when ws.shift_position = 'TI - Watchman' then (minutes_between(ws.end_time, ws.start_time)/60) end)),0) ) as total
from chat_agents a
join wiw_shifts ws on a.email = ws.user_email
left join people_ops.employees h on substr(h.email,1, instr(h.email,'#revolut') - 1) = a.login
where (seniority != 'Lead' or seniority is null)
and date_trunc('month', ws.start_time) > now() - interval '6' Month
GROUP BY 1)
I would like to divide the output of the UNION of the first one, by the result of the second one, any ideas.

Datetime SQL statement (Working in SQL Developer)

I'm new to the SQL scene but I've started to gather some data that makes sense to me after learning a little about SQL Developer. Although, I do need help with a query.
My goal:
To use the current criteria I have and select records only when the date-time value is within 5 minutes of the latest date-time. Here is my current sql statement
`SELECT ABAMS.T_WORKORDER_HIST.LINE_NO AS Line,
ABAMS.T_WORKORDER_HIST.STATE AS State,
ASMBLYTST.V_SEQ_SERIAL_ALL.BUILD_DATE,
ASMBLYTST.V_SEQ_SERIAL_ALL.SEQ_NO,
ASMBLYTST.V_SEQ_SERIAL_ALL.SEQ_NO_EXT,
ASMBLYTST.V_SEQ_SERIAL_ALL.UPD_REASON_CODE,
ABAMS.V_SERIAL_LINESET.LINESET_DATE AS "Lineset Time",
ABAMS.T_WORKORDER_HIST.SERIAL_NO AS ESN,
ABAMS.T_WORKORDER_HIST.ITEM_NO AS "Shop Order",
ABAMS.T_WORKORDER_HIST.CUST_NAME AS Customer,
ABAMS.T_ITEM_POLICY.PL_LOC_DROP_ZONE_NO AS PLDZ,
ABAMS.T_WORKORDER_HIST.CONFIG_NO AS Configuration,
ASMBLYTST.V_EDP_ENG_LAST_ABSN.LAST_ASMBLY_ABSN AS "Last Sta",
ASMBLYTST.V_LAST_ENG_LOCATION.LAST_ASMBLY_LOC,
ASMBLYTST.V_LAST_ENG_LOCATION.LAST_MES_LOC,
ASMBLYTST.V_LAST_ENG_LOCATION.LAST_ASMBLY_TIME,
ASMBLYTST.V_LAST_ENG_LOCATION.LAST_MES_TIME
FROM ABAMS.T_WORKORDER_HIST
LEFT JOIN ABAMS.V_SERIAL_LINESET
ON ABAMS.V_SERIAL_LINESET.SERIAL_NO = ABAMS.T_WORKORDER_HIST.SERIAL_NO
LEFT JOIN ASMBLYTST.V_EDP_ENG_LAST_ABSN
ON ASMBLYTST.V_EDP_ENG_LAST_ABSN.SERIAL_NO = ABAMS.T_WORKORDER_HIST.SERIAL_NO
LEFT JOIN ASMBLYTST.V_SEQ_SERIAL_ALL
ON ASMBLYTST.V_SEQ_SERIAL_ALL.SERIAL_NO = ABAMS.T_WORKORDER_HIST.SERIAL_NO
LEFT JOIN ABAMS.T_ITEM_POLICY
ON ABAMS.T_ITEM_POLICY.ITEM_NO = ABAMS.T_WORKORDER_HIST.ITEM_NO
LEFT JOIN ABAMS.T_CUR_STATUS
ON ABAMS.T_CUR_STATUS.SERIAL_NO = ABAMS.T_WORKORDER_HIST.SERIAL_NO
INNER JOIN ASMBLYTST.V_LAST_ENG_LOCATION
ON ASMBLYTST.V_LAST_ENG_LOCATION.SERIAL_NO = ABAMS.T_WORKORDER_HIST.SERIAL_NO
WHERE ABAMS.T_WORKORDER_HIST.LINE_NO = 10
AND (ABAMS.T_WORKORDER_HIST.STATE = 'PROD'
OR ABAMS.T_WORKORDER_HIST.STATE = 'SCHED')
AND ASMBLYTST.V_SEQ_SERIAL_ALL.BUILD_DATE BETWEEN TRUNC(SysDate) - 10 AND TRUNC(SysDate) + 1
AND (ABAMS.V_SERIAL_LINESET.LINESET_DATE IS NOT NULL
OR ABAMS.V_SERIAL_LINESET.LINESET_DATE IS NULL)
AND (ASMBLYTST.V_EDP_ENG_LAST_ABSN.LAST_ASMBLY_ABSN < '1800'
OR ASMBLYTST.V_EDP_ENG_LAST_ABSN.LAST_ASMBLY_ABSN IS NULL)
ORDER BY ASMBLYTST.V_EDP_ENG_LAST_ABSN.LAST_ASMBLY_ABSN DESC Nulls Last,
ABAMS.V_SERIAL_LINESET.LINESET_DATE Nulls Last,
ASMBLYTST.V_SEQ_SERIAL_ALL.BUILD_DATE,
ASMBLYTST.V_SEQ_SERIAL_ALL.SEQ_NO,
ASMBLYTST.V_SEQ_SERIAL_ALL.SEQ_NO_EXT`
Here are some of the records I get from the table
ASMBLYTST.V_LAST_ENG_LOCATION.LAST_ASMBLY_TIME
2018-06-14 01:28:25
2018-06-14 01:29:26
2018-06-14 01:27:30
2018-06-13 22:44:03
2018-06-14 01:28:45
2018-06-14 01:27:37
2018-06-14 01:27:41
What I essentially want is for
2018-06-13 22:44:03
to be excluded from the query because it is not within the 5 minute window from the latest record Which in this data set is
2018-06-14 01:29:26
The one dynamic problem i seem to have is that the values for date-time are constantly updating.
Any ideas?
Thank you!
Here are two different solutions, each uses a table called "ASET".
ASET contains 20 records 1 minute apart:
WITH
aset (ttime, cnt)
AS
(SELECT systimestamp AS ttime, 1 AS cnt
FROM DUAL
UNION ALL
SELECT ttime + INTERVAL '1' MINUTE AS ttime, cnt + 1 AS cnt
FROM aset
WHERE cnt < 20)
select * from aset;
Now using ASET for our data, the following query finds the maximum date in ASET, and restricts the results to the six records within 5 minutes of ASET:
SELECT *
FROM aset
WHERE ttime >= (SELECT MAX (ttime)
FROM aset)
- INTERVAL '5' MINUTE;
An alternative is to use an analytic function:
with bset
AS
(SELECT ttime, cnt, MAX (ttime) OVER () - ttime AS delta
FROM aset)
SELECT *
FROM bset
WHERE delta <= INTERVAL '5' MINUTE

To fetch only the hours value after performing date difference in oracle sql. Then check this hours value in where clause against an integer

My query is :
SELECT ( ( a.DATE - b.DATE ) * 24 ) AS Date_Diff,
( EXTRACT(hour FROM( a.DATE - b.DATE )) * 24 ) AS DIFF_IN_HOURS
FROM myquestion a,
myquestion b
WHERE a.question = 'My_DATE'
AND b.question = 'My_DATE'
AND a.setid = '124'
AND b.setid = '126'
It fetches me 1 record and below values:
for Date_Diff I get value - 2712 0:0:0.0
and
DIFF_IN_HOURS I get value - 0
The value in Date_Diff - '2712' is the exact number of hours difference between the two dates.
How do I get only this value and not the 0:0:0.0
I want to compare '2712' in another query in the where clause.
a.date is 08-AUG-12 12.00.00 000000000 AM
b.date is 20-NOV-12 12.00.00 000000000 AM