I have below order table,i want to retrieve records those are not in order status "processed" and cacel)status "cancelled" by today date and time(17:00 USA).Please help me to complete my issue.
order id ordername order_status cancel_status order_time cancel_time
==============================================================================================
1 Iphone processed cancelled 10/08/2012 16:00:00 10/08/2012 16:00:00
2 samsung notprocessed null null null
3 nokia processed cancelled 10/08/2012 16:00:00 10/08/2012 17:00:00
4 motorola notprocessed null null null
5 HTC processed null 10/08/2012 17:00:00 null
I tried below way but not returning any records.Please help me.
SELECT *
FROM
order
WHERE
to_char(order_time,'YYYYMMDD HH24:MI:SS')>To_char(sysdate,YYYYMMDD) || ' '|| '17:00:00'
and to_char(cancel_time,'YYYYMMDD HH24:MI:SS')>To_char(sysdate,YYYYMMDD) || ' '|| '17:00:00'
and order_time is null
and cancel_time is null
Select * from order
where
( to_char(order_time,'YYYYMMDD HH24:MI:SS')>To_char(sysdate,YYYYMMDD) || ' '|| '17:00:00'
or order_time is null )
and ( to_char(cancel_time,'YYYYMMDD HH24:MI:SS')>To_char(sysdate,YYYYMMDD) || ' '|| '17:00:00'
or cancel_time is null )
select *
from order o
where o.order_status != 'processed'
and o.cancel_status = 'cancelled'
and o.order_time < (trunc(sysdate) + 17/24)
and o.cancel_time < (trunc(sysdate) + 17/24)
Related
I have two tables. An opening hours table that says for each seller and store, which are the opening and closing times for each day of the week. The second table is the operation one which has all information about the processes.
What I need is to calculate how many seconds each process took considering only the hours when the store was opened.
I tried to solve that with case when. I solved the problem when the process take less than 2 days. But I don't know how to handle it when it takes more days. The other problem I had with this code is that case when takes a lot of time to process. Can anybody help me with these issues?
Opening hours table:
sellerid
sellerstoreid
day
dayweek
opening
closing
next_day
opening_next_day
days_to_next
123
abc
1
monday
09:00:00
17:00:00
2
09:00:00
1
123
abc
2
tuesday
09:00:00
17:00:00
4
09:00:00
2
123
abc
4
thursday
09:00:00
17:00:00
5
09:30:00
1
123
abc
5
friday
09:30:00
17:00:00
1
09:00:00
3
Where:
sellerid + sellerstoreid + day works as a primary key;
dayweek translates day from number to name;
opening and closing are the opening and closing time for that day;
opening_next_day shows the opening time o the next available date for that store and seller;
days_to_next informes in how many days will the store reopen
Process table:
delivery_id
sellerid
sellerstoreid
process
end_time
a1
123
abc
p1
05/12/2022 16:00:00.000
a1
123
abc
p2
06/12/2022 16:00:00.000
a1
123
abc
p3
06/12/2022 16:00:00.000
a1
123
abc
p4
08/12/2022 16:00:00.000
a1
123
abc
p5
13/12/2022 16:00:00.000
Where:
The end_time of the previous process will be the the start time of the process.
with
table_1 as (
select
delivery_id
, sellerid
, sellerstoreid
, process
, lag(end_time, 1) over (partition by delivery_id order by end_time) as start_time
, extract(dow from lag(end_time, 1) over (partition by delivery_id order by end_time)) as dow_start_time
, end_time
, extract(dow from end_time) as dow_end_time
from process_table
),
table_2 as (
select
table_1.*
, oh_start.opening as start_opening
, oh_start.closing as start_closing
, oh_end .opening as end_opening
, oh_end .closing as end_closing
from table_1 tb1
left join opening_hours oh_start
on oh_start.sellerid = tb1.sellerid
and oh_start.sellerstoreid = tb1.sellerstoreid
and oh_start.day = dow_start_time
left join opening_hours oh_end
on oh_end .sellerid = tb1.sellerid
and oh_end.sellerstoreid = tb1.sellerstoreid
and oh_end.day = dow_end_time
)
select
*
, case
when dow_start_time = dow_end_time then
extract(epoch from
(case
when end_time::time > start_opening then
(case
when end_time::time > start_closing then start_closing
else end_time::time
end)
else start_opening
end
-
case
when start_time::time > start_opening then
(case
when start_time::time < start_closing then start_time::time
else start_closing
end
)
else start_opening
end))
when dow_start_time <> dow_end_time then
extract(epoch from
(start_closing
-
case
when start_time::time > start_opening then
(case
when start_time::time < start_closing then start_time::time
else start_closing
end)
else start_opening
end)
+
(case
when end_time::time > end_opening then
(case
when end_time::time > end_closing then end_closing
else end_time::time
end)
else end_opening
end
-
end_opening)
end status_duration
from table_2
I wanted to make a metric data check table - below is what I have now. I wish to automate part of "2021-04-30", so every time I run the logic, it will dynamically change to the last day of every month. (iterate from 2021-01-31, 2021-02-28, 2021-03-31,.....)
CREATE TABLE data_check_result AS
WITH day_count AS (
SELECT day(date '2021-04-30' - date '2020-01-01') AS ideal_days
)
, metric AS (
SELECT country
, day(max(datepartition)- date '2020-01-01') AS actual_has_days
FROM table
GROUP BY 1
)
SELECT date '2021-04-30' AS report_period
, country
, 'metric_a' AS metric_name
, CASE WHEN metric.actual_has_days = day_count.ideal_days THEN 'YES' ELSE 'NO' END AS data_passed
FROM day_count
JOIN metric
ON 1=1
;
Ideal output table
report_period country metric_name data_passed
2021-04-30 Australia metric_a YES
2021-04-30 Canada metric_a NO
2021-04-30 China metric_a YES
2021-03-31 US metric_a NO
2021-03-31 Canada metric_a YES
....
You can use the last_day_of_month function to obtain the last day of each month:
SELECT last_day_of_month(date('2021-' || cast(month as varchar) || '-01'))
FROM UNNEST(sequence(1,12)) t(month)
=>
_col0
------------
2021-01-31
2021-02-28
2021-03-31
2021-04-30
2021-05-31
2021-06-30
2021-07-31
2021-08-31
2021-09-30
2021-10-31
2021-11-30
2021-12-31
(12 rows)
You can put it all together in this manner (not verified, but it should be a good start):
CREATE TABLE data_check_result AS
WITH metric AS (
SELECT country
, day(max(datepartition)- date '2020-01-01') AS actual_has_days
FROM table
GROUP BY 1
),
last_days_of_month AS (
SELECT last_day_of_month(date('2021-' || cast(month as varchar) || '-01')) last_day
FROM UNNEST(sequence(1,12)) t(month)
)
SELECT
last_day AS report_period
, country
, 'metric_a' AS metric_name
, CASE WHEN metric.actual_has_days = day_count.ideal_days THEN 'YES' ELSE 'NO' END AS data_passed
FROM metric
CROSS JOIN (
SELECT last_day, day(last_day - date '2020-01-01') AS ideal_days
FROM last_days_of_month
)
I have this table :
ArretProductionJournee(Id, DateArret,HeureDebut,HeureFin,EnumArret)
Example :
DateArret ||HeureDebut ||HeureFin ||EnumArret
2020-11-30 ||2020-11-30 14:00:00.000 ||2020-11-30 15:00:00.000 ||PS
2020-11-30 ||2020-11-30 16:00:00.000 ||2020-11-30 17:00:00.000 ||HI
i want to sum the datediff(HeureDebut,HeureFin) in columns for each EnumArret
so i run this query :
SELECT ArretProductionJournee.DateArret,
(select
sum (datediff(minute,ArretProductionJournee.HeureDebut,
ArretProductionJournee.HeureFin))
where ArretProductionJournee.EnumArret Like 'HI')as HI,
(select
sum (datediff(minute,ArretProductionJournee.HeureDebut,
ArretProductionJournee.HeureFin))
where ArretProductionJournee.EnumArret Like 'PS') as PS
FROM dbo.ArretProductionJournee
where ArretProductionJournee.EnumArret Like 'HI'OR
ArretProductionJournee.EnumArret Like 'PS'
group by ArretProductionJournee.EnumArret, dbo.ArretProductionJournee.DateArret
Result :
DateArret ||HI || PS
2020-10-30 ||12 || NULL
2020-11-30 ||60 || NULL
2020-11-30 ||NULL || 60
The result i want is Grouping the sum by the date:
DateArret ||HI || PS
2020-10-30 ||12 || 0
2020-11-30 ||60 || 60
I think you want conditional aggregation:
select datearret,
sum(case when enumarret = 'PS' then datediff(minute, heuredebut, heurefin) else 0 end) ps,
sum(case when enumarret = 'HI' then datediff(minute, heuredebut, heurefin) else 0 end) hi
from dbo.arretproductionjournee
where enumarret in ('PS', 'HI')
group by datearret
Table 1: Daily attendance data:
att_date emp_code emp_name in_time out_time
2018-10-21 9999 Test 2018-10-21 08:00:00.000 2018-10-22 06:00:00.000
Table 2: Trnevents
emp_readr_id DT EVENTID
9999 2018-10-24 07:00:00.000 0
9999 2018-10-24 05:00:00.000 0
9999 2018-10-24 03:00:00.000 0
9999 2018-10-23 21:00:00.000 0
9999 2018-10-23 19:00:00.000 0
9999 2018-10-23 06:00:00.000 0
9999 2018-10-22 06:00:00.000 0
9999 2018-10-21 08:00:00.000 0
I used this query to get all times in between in time and out time ,below query works fine but i try to make in row by using pivot. While using pivot out time shows in next row.
declare #tempProcesstable as table(
[id] [nvarchar](200) NULL,
[time_stamp] datetime NULL,
[AccessType] varchar(3) NULL)
insert into #tempProcesstable
select distinct t1.emp_Reader_id, t1.DT,t1.eventid from daily_attendance_data t2 join trnevents t1
on t1.emp_reader_id=t2.emp_reader_id where (CONVERT(VARCHAR(26), t2.att_Date, 23) >=CONVERT(VARCHAR(26), '2018-10-20', 23)
and CONVERT(VARCHAR(26), t2.att_date, 23) <=CONVERT(VARCHAR(26), '2018-10-21', 23))
and
(t1.DT >=t2.in_time
and t1.DT <=t2.out_time)
-- and t1.emp_reader_id=1000
group by t1.emp_Reader_id,t1.dt,t1.eventid order by t1.emp_reader_id,DT asc
; With CheckIns
As (Select Rowemp_reader_id = Row_Number() Over (Partition by id, Cast(time_stamp As Date) Order By time_stamp),
id, time_stamp,
[Date] = Cast(time_stamp As Date),
[Time] = Cast(time_stamp As Time(0))
From #tempProcesstable)
Select Pvt.id,B.emp_name , [Date], CHECK1, CHECK2,Cast(dateadd(ss,datediff(ss,CHECK1,CHECK2),0) As Time(0)) Total1,
CHECK3, CHECK4,Cast(dateadd(ss,datediff(ss,CHECK3,CHECK4),0) As Time(0)) Total2
From (Select id, [Date], [Time],
CHECKNum = 'CHECK' + Cast(Rowemp_reader_id As varchar(11))
From CheckIns) As P
Pivot (Min([Time])
For CheckNum In (Check1, [Check2], Check3, Check4)
) As Pvt
LEFT OUTER JOIN
dbo.employee AS B ON Pvt.id= B.emp_reader_id
My output:
id emp_name Date CHECK1 CHECK2 Total1 CHECK3 CHECK4 Total2
1048 Singh 2018-10-21 07:06:07 17:34:05 10:27:58 NULL NULL NULL
9999 Test 2018-10-21 08:00:00 NULL NULL NULL NULL NULL NULL
9999 Test 2018-10-22 06:00:00 NULL NULL NULL NULL NULL NULL
Expected output:
I want all times between in time and out time in night to morning also.
can any one help me to rectify this.
id emp_name Date CHECK1 CHECK2 Total1 CHECK3 CHECK4 Total2
1048 Singh 2018-10-21 07:06:07 17:34:05 10:27:58 NULL NULL NULL
9999 Test 2018-10-21 08:00:00 06:00:00 NULL NULL NULL NULL NULL
You can try to use ROW_NUMBER() window function make row number by each date.
then use condition aggregate function to do pivot
SELECT emp_readr_id,
emp_name,
[Date],
MAX(CASE WHEN RN = 1 THEN time END) CHECK1,
MAX(CASE WHEN RN = 2 THEN time END) CHECK2,
MAX(CASE WHEN RN = 3 THEN time END) CHECK3,
MAX(CASE WHEN RN = 4 THEN time END) CHECK4
FROM (
SELECT emp_readr_id,
emp_name,
CONVERT(VARCHAR(10),DT,120) 'Date',
ROW_NUMBER() OVER(PARTITION BY CONVERT(VARCHAR(10),DT,120) ORDER BY DT) rn,
CONVERT(VARCHAR(10),DT,108) time
FROM Daily d
JOIN Trnevents t on t.DT between d.in_time and d.out_time
) t1
group by emp_readr_id,
emp_name,
[Date]
sqlifddle
I am trying to adjust the below code by adding a 2 week tolerance piece.
What it does it looks when the first time a customer (identifier) created a request and the first time it was completed and counts the days which happened in between.
However I am trying to add a tolerance piece. Which says count the number of NCO which occurred between those dates and if there were further requests past the completion date which happened within 2 weeks of the completion date then count those as well (part of the same request). Anything past 2 weeks of the completions date consider as a new request.
CREATE TABLE #temp
(
Identifier varchar(40)NOT NULL
,Created_Date DATETIME NOT NULL
,Completed_Date DATETIME NULL
,SN_Type varchar(20) NOT NULL
,SN_Status varchar(20) NOT NULL
)
;
INSERT INTO #temp
VALUES ('3333333','2017-02-14 15:00:40.000','2017-02-15 00:00:00.000','Re-Activattion', 'COMP');
INSERT INTO #temp
VALUES ('3333333','2017-05-24 16:41:04.000','2017-06-05 00:00:00.000','Re-Activattion', 'N-CO');
INSERT INTO #temp
VALUES ('3333333','2017-05-25 11:49:54.000','2017-05-26 00:00:00.000','Re-Activattion', 'COMP');
INSERT INTO #temp
VALUES ('3333333','2017-06-27 10:24:29.000',NULL,'Re-Activattion', 'ACC');
#Alex you code is accurate just I would like to be selecting the min date the record is created a 2nd time, so line 2 of the result should return min date to be 2017-05-24 16:41:04.000.
select identifier
,case
when sum(case when SN_STATUS='COMP' and SN_TYPE = 'Re-Activattion' then 1 else 0 end)>0
then str(datediff(day
,MIN(case
when SN_TYPE = 'Re-Activattion'
then Created_Date
else null
end
)
,min(case
when (SN_TYPE = 'Re-Activattion'
and SN_STATUS='COMP'
)
then Completed_Date
else null
end
)
)
)
when sum(case when SN_TYPE='Re-Activattion' then 1 else 0 end)>0
then 'NOT COMP'
else 'NO RE-ACT'
end
as RE_ACT_COMPLETION_TIME
,Sum(CASE WHEN SN_STATUS = 'N-CO' THEN 1 ELSE 0 END) as [RE-AN NCO #]
from #temp
group by identifier
;
RESULTS I AM AFTER:
Your table design is not optimal for these kinds of queries as there is no definitive record that specified order start and order end. Additionally multiple orders are stored with the same identifier.
To work around this you need to calculate/identify Order start and Order End records yourself.
One way to do it is using Common Table Expressions.
Note: I have added comments to code to explain what each section does.
-- calculate/identify Order start and Order End records
WITH cte AS
(
-- 1st Order start record i.e. earliest record in the table for a given "Identifier"
SELECT Identifier, MIN( Created_Date ) AS Created_Date, CONVERT( VARCHAR( 30 ), 'Created' ) AS RecordType, 1 AS OrderNumber
FROM #temp
GROUP BY Identifier
UNION ALL
-- All records with "COMP" status are treated as order completed events. Add 2 weeks to the completed date to create a "dummy" Order End Date
SELECT Identifier, DATEADD( WEEK, 2, Created_Date ) AS Created_Date, 'Completed' AS RecordType, ROW_NUMBER() OVER( PARTITION BY Identifier ORDER BY Created_Date ) AS OrderNumber
FROM #temp
WHERE SN_STATUS = 'COMP'
UNION ALL
-- Set the start period of the next order to be right after (3 ms) the previous Order End Date
SELECT Identifier, DATEADD( ms, 3, DATEADD( WEEK, 2, Created_Date )) AS Created_Date, 'Created' AS RecordType, ROW_NUMBER() OVER( PARTITION BY Identifier ORDER BY Created_Date ) + 1 AS OrderNumber
FROM #temp
WHERE SN_STATUS = 'COMP'
),
-- Combine Start / End records into one record
OrderGroups AS(
SELECT Identifier, OrderNumber, MIN( Created_Date ) AS OrderRangeStartDate, MAX( Created_Date ) AS OrderRangeEndDate
FROM cte
GROUP BY Identifier, OrderNumber
)
SELECT a.Identifier, a.OrderNumber, OrderRangeStartDate, OrderRangeEndDate,
case
when sum(case when SN_STATUS='COMP' and SN_TYPE = 'Re-Activattion' then 1 else 0 end)>0
then str(datediff(day
,MIN(case
when SN_TYPE = 'Re-Activattion'
then Created_Date
else null
end
)
,min(case
when (SN_TYPE = 'Re-Activattion'
and SN_STATUS='COMP'
)
then Completed_Date
else null
end
)
)
)
when sum(case when SN_TYPE='Re-Activattion' then 1 else 0 end)>0
then 'NOT COMP'
else 'NO RE-ACT'
end as RE_ACT_COMPLETION_TIME,
Sum(CASE WHEN SN_STATUS = 'N-CO' THEN 1 ELSE 0 END) as [RE-AN NCO #]
FROM OrderGroups AS a
INNER JOIN #Temp AS b ON a.Identifier = b.Identifier AND a.OrderRangeStartDate <= b.Created_Date AND b.Created_Date <= a.OrderRangeEndDate
GROUP BY a.Identifier, a.OrderNumber, OrderRangeStartDate, OrderRangeEndDate
Output:
Identifier OrderNumber OrderRangeStartDate OrderRangeEndDate RE_ACT_COMPLETION_TIME RE-AN NCO #
-------------- ------------- ----------------------- ----------------------- ---------------------- -----------
200895691 1 2016-01-27 14:25:00.000 2016-02-10 15:15:00.000 0 2
200895691 2 2016-02-10 15:15:00.003 2017-01-16 12:15:00.000 1 1
Output for the updated data set:
Identifier OrderNumber OrderRangeStartDate OrderRangeEndDate RE_ACT_COMPLETION_TIME RE-AN NCO #
------------ ------------ ----------------------- ----------------------- ---------------------- -----------
200895691 1 2017-01-11 00:00:00.000 2017-03-27 00:00:00.000 61 4
200895691 2 2017-03-27 00:00:00.003 2017-04-20 00:00:00.000 1 1
3333333 1 2017-01-27 00:00:00.000 2017-02-10 00:00:00.000 0 2
44454544 1 2017-01-27 00:00:00.000 2017-01-27 00:00:00.000 NOT COMP 1
7777691 1 2017-02-08 09:36:44.000 2017-02-22 09:36:44.000 63 1
Update 2017-10-05 in response to the comment
Input:
INSERT INTO #temp VALUES
('11111','20170203','20170203','Re-Activattion', 'COMP'),
('11111','20170206','20170202','Re-Activattion', 'N-CO');
Output:
Identifier OrderNumber OrderRangeStartDate OrderRangeEndDate RE_ACT_COMPLETION_TIME RE-AN NCO #
---------- ------------ ----------------------- ----------------------- ---------------------- -----------
11111 1 2017-02-03 00:00:00.000 2017-02-17 00:00:00.000 0 1