Select all table in 2 table with null value - sql

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

Related

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)))

Querying sequential data with date/time and text values in the same column

My data is single field, and include date, time, hour but also include data that i need.
Already query 2 keyword but the data still big and too many empty second keyword
SELECT Field1
FROM TABLE1
WHERE Field1 Like '*EVENT_1' Or
Field1 Like '*DATETIME'
I expect the output is:
Thanks in advance
Start by importing your log data into Access. While doing so, tell Access to create its own Primary Key, which will be an AutoNumber:
[impLogData]
ID Field1
-- ------------------
1 May/01/2019 7:00
2 EVENT_0
3 EVENT_1 - val:10
4 EVENT_2
5 EVENT_3
6 EVENT_4
7 EVENT_5
8 EVENT_6
9 May/01/2019 8:00
10 EVENT_2
11 EVENT_3
12 EVENT_12
13 EVENT_13
14 EVENT_14
15 May/01/2019 9:00
16 EVENT_0
17 EVENT_1 - val:15
18 EVENT_2
Create a [tblLogTime] table as
ID - Long Integer, Primary Key
logTime - Date/Time
and populate it with
INSERT INTO tblLogTime ( ID, logTime )
SELECT impLogData.ID, CDate([Field1]) AS Expr1
FROM impLogData
WHERE (((IsDate([Field1]))=True));
producing
[tblLogTime]
ID logTime
-- -------------------
1 2019-05-01 07:00:00
9 2019-05-01 08:00:00
15 2019-05-01 09:00:00
Then create a [tblLogEvent] table as
logTime - Date/Time
logEvent - Text(255)
and populate it with
INSERT INTO tblLogEvent ( logTime, logEvent )
SELECT DMax("logTime","tblLogTime","ID < " & [impLogData].[ID]) AS Expr1, impLogData.Field1
FROM impLogData LEFT JOIN tblLogTime ON impLogData.ID = tblLogTime.ID
WHERE (((tblLogTime.ID) Is Null));
producing
[tblLogEvent]
logTime logEvent
------------------- ----------------
2019-05-01 07:00:00 EVENT_0
2019-05-01 07:00:00 EVENT_1 - val:10
2019-05-01 07:00:00 EVENT_2
2019-05-01 07:00:00 EVENT_3
2019-05-01 07:00:00 EVENT_4
2019-05-01 07:00:00 EVENT_5
2019-05-01 07:00:00 EVENT_6
2019-05-01 08:00:00 EVENT_2
2019-05-01 08:00:00 EVENT_3
2019-05-01 08:00:00 EVENT_12
2019-05-01 08:00:00 EVENT_13
2019-05-01 08:00:00 EVENT_14
2019-05-01 09:00:00 EVENT_0
2019-05-01 09:00:00 EVENT_1 - val:15
2019-05-01 09:00:00 EVENT_2
You can then select EVENT_1 rows using
SELECT tblLogEvent.logTime, tblLogEvent.logEvent
FROM tblLogEvent
WHERE (((tblLogEvent.logEvent) Like "EVENT_1 *"))
ORDER BY tblLogEvent.logTime;
producing
logTime logEvent
------------------- ----------------
2019-05-01 07:00:00 EVENT_1 - val:10
2019-05-01 09:00:00 EVENT_1 - val:15

Get temperature from live data if available, else avg over historical data

I am trying to get either live temperature for a trip, if live data is not available get an average temperature from histroical data.
I have made a simple version of my problem, with these tabels:
Trip
id departure_time arrival_time location_id
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1
Location
id name
1 Location
Weather
id temperature date location_id
1 20 2018-04-07 1
2 20 2018-04-08 1
3 20 2018-04-09 1
4 20 2018-04-10 1
5 20 2018-04-11 1
6 20 2018-04-12 1
7 20 2018-04-13 1
8 20 2018-04-14 1
9 15 2016-04-07 1
10 15 2016-04-08 1
11 15 2016-04-09 1
12 15 2016-04-10 1
13 15 2016-04-11 1
14 15 2016-04-12 1
15 15 2016-04-13 1
16 15 2016-04-14 1
17 19 2017-04-07 1
18 19 2017-04-08 1
19 19 2017-04-09 1
20 19 2017-04-10 1
21 19 2017-04-11 1
22 19 2017-04-12 1
23 19 2017-04-13 1
24 19 2017-04-14 1
25 15 2017-04-15 1
26 15 2017-04-16 1
27 15 2017-04-17 1
28 15 2017-04-18 1
29 15 2017-04-19 1
30 15 2017-04-20 1
31 15 2017-04-21 1
32 19 2016-04-15 1
33 19 2016-04-16 1
34 19 2016-04-17 1
35 19 2016-04-18 1
36 19 2016-04-19 1
37 19 2016-04-20 1
38 19 2016-04-21 1
The problem i am having is that since these trips are last-minute trips i have "live" data for trips departing within the next week.
So i would like to get a either live forecast if available, else an avg for the temperature from the years from the previous years.
http://sqlfiddle.com/#!17/bce59/3
Here is the approach i took in order to try and solve the problem.
If any details has been forgotten please ask.
Expected result:
id departure_time arrival_time location_id temperature
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 20
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 17
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 17
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 17
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 17
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 17
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 17
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 17
Using generate_series function to make a Calendar from trip table on subquery.
Then Left JOIN on subquery by dates you might get match weather you can get it temperature. if temperature is null on w.temperature then get avg temperature
You can try this.
SELECT t.id,
t.departure_time,
t.arrival_time,
l.id as "location_id",
coalesce(w.temperature,(select FLOOR(avg(temperature)) from weather)) as "temperature"
FROM
location l inner join
(
select id,
location_id,
departure_time,
arrival_time,
generate_series(departure_time :: timestamp,arrival_time::timestamp,'1 day'::interval) as dates
from trip
) t on t.location_id = l.id LEFT JOIN weather w on t.dates::date = w.date::date
sqlfiddle:http://sqlfiddle.com/#!17/bce59/48
EDIT
You could use a CTE query get Avg by year instead of the subquery in coalesce function on select clause.
WITH weather_avg AS (
SELECT floor(avg(a)) avgTemp
from
(
SELECT
extract(YEAR from weather.date) AS YEAR,
floor(avg(weather.temperature)) a
FROM weather
group by extract(YEAR from weather.date)
) t
)
SELECT t.id,
t.departure_time,
t.arrival_time,
t.location_id as "location_id",
coalesce(w.temperature,(select avgTemp from weather_avg)) as "temperature"
FROM
(
select t.id,
t.location_id,
t.departure_time,
t.arrival_time,
generate_series(departure_time :: timestamp,arrival_time::timestamp,'1 day'::interval) as dates
from trip t inner join location l on t.location_id = l.id
) t LEFT JOIN weather w
on t.dates::date = w.date::date
sqlfiddle:http://sqlfiddle.com/#!17/bce59/76

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

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

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;