How to add leading zero in a number in Oracle with to_number function - sql

create or replace FUNCTION OT_TIMMING_CHECK
(V_OT_ROOM_ID NUMBER,V_OPERATION_DATE DATE,V_START_TIME VARCHAR2,
V_END_TIME VARCHAR2)
RETURN NUMBER AS
V_STATUS_1 VARCHAR2(10);
V_STATUS_2 VARCHAR2(10);
V_STATUS_3 VARCHAR2(10);
V_STATUS_4 VARCHAR2(10);
V_STATUS_5 VARCHAR2(10);
V_STATUS_6 VARCHAR2(10);
C_END_TIME NUMBER;
C_START_TIME NUMBER;
F_OPERATION_DATE DATE;
V_COUNT NUMBER :=0;
b_start_time varchar(10);
BEGIN
SELECT OPERATION_DATE INTO F_OPERATION_DATE FROM OT_THEATRE_STATUS_TBL1
WHERE OPERATION_DATE = V_OPERATION_DATE AND ROWNUM<2 ;
SELECT (case when (substr(V_START_TIME,1,instr(V_START_TIME,':')-1))='00'
then 24
else to_number(substr(V_START_TIME,1,instr(V_START_TIME,':')-1)) end) INTO
C_START_TIME from dual;
SELECT (case when (substr(V_END_TIME,1,instr(V_END_TIME,':')-1))='00' then
24 else to_number(substr(V_END_TIME,1,instr(V_END_TIME,':')-1)) end) INTO
C_END_TIME from dual;
IF V_OT_ROOM_ID=1 AND F_OPERATION_DATE = V_OPERATION_DATE THEN
WHILE (C_START_TIME < C_END_TIME)
LOOP
SELECT STATUS_1 INTO V_STATUS_1 FROM OT_THEATRE_STATUS_TBL1
WHERE START_TIME=concat(to_char(C_START_TIME),':00:00')
AND END_TIME= REPLACE(concat(to_char(C_START_TIME+1),':00:00'),24,'00');
IF(V_STATUS_1 ='Booked' OR V_STATUS_1='Pending') then
RETURN 1;
ELSE
C_START_TIME:= TO_CHAR(C_START_TIME+1);
V_COUNT:=V_COUNT+1;
end if;
END LOOP;
RETURN 0;
END IF ;
END;
Database structure is like this
V_START_TIME V_END_TIME OPERATION_Date STATUS_1 OT_ROOM_ID_1
01:00:00 01:00:00 24-Mar-17 AVAILABLE 1
02:00:00 02:00:00 24-Mar-17 LAPSED 1
03:00:00 03:00:00 24-Mar-17 AVAILABLE 1
04:00:00 04:00:00 24-Mar-17 AVAILABLE 1
05:00:00 05:00:00 24-Mar-17 AVAILABLE 1
06:00:00 06:00:00 24-Mar-17 AVAILABLE 1
07:00:00 07:00:00 24-Mar-17 AVAILABLE 1
08:00:00 08:00:00 24-Mar-17 AVAILABLE 1
09:00:00 09:00:00 24-Mar-17 AVAILABLE 1
10:00:00 10:00:00 24-Mar-17 AVAILABLE 1
11:00:00 11:00:00 24-Mar-17 AVAILABLE 1
12:00:00 12:00:00 24-Mar-17 AVAILABLE 1
13:00:00 13:00:00 24-Mar-17 BOOKING 1
14:00:00 14:00:00 24-Mar-17 AVAILABLE 1
15:00:00 15:00:00 24-Mar-17 AVAILABLE 1
16:00:00 16:00:00 24-Mar-17 AVAILABLE 1
17:00:00 17:00:00 24-Mar-17 AVAILABLE 1
18:00:00 18:00:00 24-Mar-17 AVAILABLE 1
19:00:00 19:00:00 24-Mar-17 AVAILABLE 1
20:00:00 20:00:00 24-Mar-17 AVAILABLE 1
21:00:00 21:00:00 24-Mar-17 AVAILABLE 1
22:00:00 22:00:00 24-Mar-17 AVAILABLE 1
23:00:00 23:00:00 24-Mar-17 AVAILABLE 1
00:00:00 00:00:00 24-Mar-17 AVAILABLE 1
Earlier V_START_TIME like '1:00:00:00' but now it is leading with 0. Then problem comes. Now it is returning null. How to come out from this problem.

Number won't be having leading zero's
Can you try the following:
LPAD(to_number(SUBSTR('01:00:00',1,instr('01:00:00',':')-1)),2, 0)
reference:
How to display the leading zero's in a number of oracle

yes, try it
SELECT (
CASE
WHEN (SUBSTR('01:00:00',1,instr('01:00:00',':')-1))='00'
THEN '24'
ELSE LPAD(SUBSTR('01:00:00',1,instr('01:00:00',':')-1),2,'0')
END)
FROM dual;

Related

Pandas replace daily observations by monthly mean

Suppose, I have a pandas Series with daily observations:
pd_series = pd.Series(np.random.rand(26281), index = pd.date_range('2022-01-01', '2024-12-31', freq = 'H'))
pd_series
2022-01-01 00:00:00 0.933746
2022-01-01 01:00:00 0.588907
2022-01-01 02:00:00 0.229040
2022-01-01 03:00:00 0.557752
2022-01-01 04:00:00 0.798649
2024-12-30 20:00:00 0.314143
2024-12-30 21:00:00 0.670485
2024-12-30 22:00:00 0.300531
2024-12-30 23:00:00 0.075403
2024-12-31 00:00:00 0.716685
What I want is to replace every observation by the monthly average. I know that the average can be calculated as
pd_series.resample('MS').mean()
But how do I put the observations to the respective observations?
Use Resampler.transform:
print (pd_series.resample('MS').transform('mean'))
2022-01-01 00:00:00 0.495015
2022-01-01 01:00:00 0.495015
2022-01-01 02:00:00 0.495015
2022-01-01 03:00:00 0.495015
2022-01-01 04:00:00 0.495015
2024-12-30 20:00:00 0.508646
2024-12-30 21:00:00 0.508646
2024-12-30 22:00:00 0.508646
2024-12-30 23:00:00 0.508646
2024-12-31 00:00:00 0.508646
Freq: H, Length: 26281, dtype: float64

Overlap in seconds between datetime range and a time range

I have a dataframe like this:
df11 = pd.DataFrame(
{
"Start_date": ["2018-01-31 12:00:00", "2018-02-28 16:00:00", "2018-02-27 22:00:00"],
"End_date": ["2019-01-31 21:45:00", "2019-03-24 22:00:00", "2018-02-28 01:00:00"],
}
)
Start_date End_date
0 2018-01-31 12:00:00 2019-01-31 21:45:00
1 2018-02-28 16:00:00 2019-03-24 22:00:00
2 2018-02-27 22:00:00 2018-02-28 01:00:00
I need to check the overlap time duration in specific periods in seconds. My expected results are like this:
Start_date End_date 12h-16h 16h-22h 22h-00h 00h-02h30
0 2018-01-31 12:00:00 2019-01-31 21:45:00 14400 20700 0 0
1 2018-02-28 16:00:00 2019-03-24 22:00:00 0 21600 0 0
2 2018-02-27 22:00:00 2018-02-28 01:00:00 0 0 7200 3600
I know it`s completely wrong and I´ve tried other solutions. This is one of my attempts:
df11['12h-16h']=np.where(df11['Start_date']<timedelta(hours=16, minutes=0, seconds=0) & df11['End_date']>timedelta(hours=12, minutes=0, seconds=0),(np.minimum(df11['End_date'],timedelta(hours=16, minutes=0, seconds=0)))-(np.maximum(df11['Start_date'],timedelta(hours=12, minutes=0, seconds=0)))

Total time calculation in a sql query for a day where time in 24 hour format as hhmm

I have a table with date(date), left time(varchar2(4)) and arrival time(varchar2(4)). Time taken is in 24 hour format as hhmm. If a person travel 3 times a day, what will be the query to calculate total travel time in a day?
I am using oracle 11g. Kindly help. Thank you.
Convert the value to a number and report in minutes:
select to_number(substring(time, 1, 2))*60 + to_number(substring(time, 3, 2)) as minutes
Your query would look something like:
select person, sum(to_number(substring(time, 1, 2))*60 + to_number(substring(time, 3, 2))) as minutes
from t
group by person;
I see no reason to convert this back to a string -- or to even store the value as a string instead of as a number. But if you need to, you can reverse the process to get a string.
There are 2 answers, If you want to sum time only on date then it can be done as:-
select curr_date,
sum(24 * (to_date(arrival_time, 'HH24:mi:ss')- to_date(left_time, 'HH24:mi:ss'))) as difference
from sql_prac group by curr_date,arrival_time,left_time;
The sample output is as follows:-
select curr_date,left_time,arrival_time from sql_prac;
CURR_DATE LEFT_TIME ARRIVAL_TIME
--------- -------------------- --------------------
30-JUN-17 00:00:00 15:00:00
30-JUL-17 03:30:00 11:30:00
30-AUG-17 03:00:00 12:30:00
30-SEP-17 04:00:00 17:00:00
30-JUN-17 00:00:00 15:00:00
30-JUL-17 03:30:00 11:30:00
30-AUG-17 03:00:00 12:30:00
30-SEP-17 04:00:00 17:00:00
30-SEP-17 04:00:00 17:00:00
9 rows selected
select curr_date,sum(24 * (to_date(arrival_time, 'HH24:mi:ss')- to_date(left_time, 'HH24:mi:ss'))) as difference
from sql_prac group by curr_date,arrival_time,left_time;
CURR_DATE DIFFERENCE
--------- ----------
30-JUN-17 30
30-JUL-17 16
30-SEP-17 39
30-AUG-17 19
If you want to sum it by person and date then it can be done as:-
select dept,curr_date,sum(24 * (to_date(arrival_time, 'HH24:mi:ss')- to_date(left_time, 'HH24:mi:ss'))) as difference
from sql_prac group by dept,curr_date,arrival_time,left_time order by Dept;
The sample output is as follows:-
Data in table is:-
select dept,curr_date,left_time,arrival_time from sql_prac;
DEPT CURR_DATE LEFT_TIME ARRIVAL_TIME
-------------------- --------- -------------------- --------------------
A 30-SEP-17 04:00:00 17:00:00
B 30-SEP-17 04:00:00 17:00:00
C 30-AUG-17 03:00:00 12:30:00
D 30-DEC-17 04:00:00 17:00:00
A 30-SEP-17 04:00:00 17:00:00
B 30-JUL-17 03:30:00 11:30:00
C 30-AUG-17 03:00:00 12:30:00
D 30-SEP-17 04:00:00 17:00:00
R 30-SEP-17 04:00:00 17:00:00
Data fetched using the query
select dept,curr_date,sum(24 * (to_date(arrival_time, 'HH24:mi:ss')- to_date(left_time, 'HH24:mi:ss'))) as difference
from sql_prac group by dept,curr_date,arrival_time,left_time order by Dept;
DEPT CURR_DATE DIFFERENCE
-------------------- --------- ----------
A 30-SEP-17 26
B 30-JUL-17 8
B 30-SEP-17 13
C 30-AUG-17 19
D 30-SEP-17 13
D 30-DEC-17 13
R 30-SEP-17 13

Select all table in 2 table with null value

I Have 2 Table in SQL SERVER 2005:
first table :
Tanggal
2015/01/01
2015/01/02
2015/01/03
2015/01/04
2015/01/05
2015/01/06
Second Table :
Tanggal Jam_Masuk Jam_Pulang. Id_user
2015/01/01 08:00:00 17:00:00 00600320
2015/01/03 08:00:00 17:00:00 00600320
2015/01/05 08:00:00 17:00:00 00600320
2015/01/06 08:00:00 17:00:00 00600320
I want select like this :
Tanggal Jam_Masuk Jam_Pulang Total Status Id_user
2015/01/01 08:00:00 17:00:00 09:00:00 OK 00600320
2015/01/02 --:--:-- --:--:-- --:--:-- ALPHA/IZIN 00600320
2015/01/03 08:00:00 17:00:00 09:00:00 OK 00600320
2015/01/04 --:--:-- --:-- :-- --:--:-- ALPHA/IZIN 00600320
2015/01/05 08:00:00 17:00:00 09:00:00 OK 00600320
2015/01/06 08:00:00 17:00:00 09:00:00 OK 00600320
Note : Field Total (hh:mm:ss)= Jam_Pulang - Jam_Masuk
Thanks Before
LEFT JOIN the two tables, Use a CASE statement for the Status and use the DATEDIFF function for the total. Also use CONVERT for the datestamp Tanggal with style 111 for your expected output of YYYY/MM/DD.
SELECT CONVERT(VARCHAR(50),a.Tanggal,111) AS Tanggal,
b.Jam_Masuk,
b.Jam_Pulang,
DATEDIFF(hour, Jam_Masuk, Jam_Pulang) AS Total,
b.Id_user,
CASE WHEN b.Id_user IS NOT NULL THEN 'OK' ELSE NULL END AS Status
FROM tab1 a
LEFT JOIN tab12 b ON a.Tanggal = b.Tanggal
OUTPUT
Tanggal Jam_Masuk Jam_Pulang Total Id_user Status
2015/01/01 08:00:00 17:00:00 9 600320 OK
2015/01/02 (null) (null) (null) (null) (null)
2015/01/03 08:00:00 17:00:00 9 600320 OK
2015/01/04 (null) (null) (null) (null) (null)
2015/01/05 08:00:00 17:00:00 9 600320 OK
2015/01/06 08:00:00 17:00:00 9 600320 OK

SQL Multiple record : Time Scheduler

I have problem about combining tables in store procedure.
Note : field "Time" is varchar
First table (tbTime)
Time
08:00:00
08:30:00
09:00:00
09:30:00
10:00:00
10:30:00
11:00:00
11:30:00
12:00:00
12:30:00
13:00:00
13:30:00
14:00:00
14:30:00
15:00:00
15:30:00
16:00:00
16:30:00
17:00:00
17:30:00
18:00:00
18:30:00
19:00:00
19:30:00
20:00:00
Second table (tbClassRsv)
select * from tbclassrsv where transdate='2014-02-05 00:00:00' and status<>'DEL'
transDate time until status studentCode tutor class description userID
2014-02-05 16:48:14 17:48:14 OPN ET-7201 ET-444 ROOM 01 try ADMIN
I want the result with condition schedule like this
Time Student
08:00:00 -
08:30:00 -
09:00:00 -
09:30:00 -
10:00:00 -
10:30:00 -
11:00:00 -
11:30:00 -
12:00:00 -
12:30:00 -
13:00:00 -
13:30:00 -
14:00:00 -
14:30:00 -
15:00:00 -
15:30:00 -
16:00:00 -
16:30:00 ET-7201
17:00:00 ET-7201
17:30:00 ET-7201
18:00:00 ET-7201
18:30:00 -
19:00:00 -
19:30:00 -
20:00:00 -
Thanks for reading or answer ^_^
GBU
I`ve tried this
select t.time,
isnull(
(select c.studentCode
from tbclassrsv c
where c.transdate='2014-02-05 00:00:00'
and c.class='ROOM 01'
and c.status<>'DEL'
and t.time>=c.time
and t.time<=c.until
),'-') [Student]
The result is....
Time Student
08:00:00 -
08:30:00 -
09:00:00 -
09:30:00 -
10:00:00 -
10:30:00 -
11:00:00 -
11:30:00 -
12:00:00 -
12:30:00 -
13:00:00 -
13:30:00 -
14:00:00 -
14:30:00 -
15:00:00 -
15:30:00 -
16:00:00 -
16:30:00 -
17:00:00 ET-7201
17:30:00 ET-7201
18:00:00 -
18:30:00 -
19:00:00 -
19:30:00 -
20:00:00 -
Try this. you were not converting your varchar times to datetime so that your time comparisons would work.
select t.time,
isnull(
(select c.studentCode
from tbClassRsv c
where c.transdate='2014-02-05 00:00:00'
and c.class='ROOM 01'
and c.status<>'DEL'
and DateAdd(MINUTE, 30, Convert(datetime, t.time))>= Convert(datetime, c.time)
and Convert(datetime, t.time) <= Convert(datetime, c.until)
),'-') from [tbTime] t
What you need to do is round c.time down to the nearest 30 minutes interval, and round c.until up to the nearest interval. This way your where clause will have the correct range.
To do the rounding you will need to convert the times to datetime which you can do like so:
CAST(CONVERT(varchar,THE_TIME_AS_VARCHAR,121) AS datetime)
Then you can round down to the nearest 30 minutes like so:
DATEADD(mi, DATEDIFF(mi, 0, THE_TIME_AS_DATETIME)/30*30, 0)
And round up like so:
DATEADD(mi, DATEDIFF(mi, 30, THE_TIME_AS_DATETIME)/30*30, 0)
Applying all that to your existing code would give you this:
select t.time,
isnull(
(select c.studentCode
from tbclassrsv c
where c.transdate='2014-02-05 00:00:00'
and c.class='ROOM 01'
and c.status<>'DEL'
and t.time>= DATEADD(mi, DATEDIFF(mi, 0, CAST(CONVERT(varchar,c.time,121) AS datetime))/30*30, 0)
and t.time<= DATEADD(mi, DATEDIFF(mi, 30, CAST(CONVERT(varchar,c.until,121) AS datetime))/30*30, 0)
),'-') [Student]