I have a record as below
ID(int) DATA_ORA(timestamp) BADGE LETTORE
1 2017-04-01 09:30:00 1 1
2 2017-04-01 12:30:00 1 2
3 2017-04-01 13:30:00 1 1
4 2017-04-01 18:30:00 1 2
5 2017-04-01 09:30:00 2 1
6 2017-04-01 18:30:00 2 2
7 2017-04-02 09:30:00 1 1
8 2017-04-02 18:30:00 1 2
9 2017-04-03 09:30:00 3 1
10 2017-04-03 12:30:00 3 2
11 2017-04-03 13:30:00 3 1
12 2017-04-03 18:30:00 3 2
I want to get the first access time and the last daily logout time (for each day) for each individual user (badge).
How I can do this?
The record I wish to as below
ID(int) DATA_ORA(timestamp) BADGE LETTORE
1 2017-04-01 09:30:00 1 1
4 2017-04-01 18:30:00 1 2
5 2017-04-01 09:30:00 2 1
6 2017-04-01 18:30:00 2 2
7 2017-04-02 09:30:00 1 1
8 2017-04-02 18:30:00 1 2
9 2017-04-03 09:30:00 3 1
12 2017-04-03 18:30:00 3 2
Is it possible to do that? Thanks.
NOTE: ID are auto-incremented and LETTORE 1 is entry and LETTORE 2 is exit.
You can do it grouping by date, badge and lettore like:
SELECT date(DATA_ORA),badge,lettore, case when lettore=1 then min(time(data_ora))
when lettore=2 then max(time(data_ora))
else 0
end
FROM table1
group by date(DATA_ORA),badge,lettore
try below using correlated subquery and union all
select * from tablename a
where DATA_ORA in (select min(DATA_ORA) from tablename b where a.badge=b.badge)
union
select * from tablename a
where DATA_ORA in (select max(DATA_ORA) from tablename b where a.badge=b.badge)
I like #fa06 answer, but he misses, that you want the data daily.
so try this:
select * from t1 a
where DATA_ORA in (select min(DATA_ORA) from t1 b where a.badge=b.badge GROUP BY DATE_FORMAT(DATA_ORA, '%Y%m%d'))
union
select * from t1 a
where DATA_ORA in (select max(DATA_ORA) from t1 b where a.badge=b.badge GROUP BY DATE_FORMAT(DATA_ORA, '%Y%m%d'));
Here is the executed version of your table and query that gives output in the order you needed, on DB-fiddle.
Try this query:
select * from EntryExitLogs where id in
(select id from EntryExitLogs where (badge,data_ora)= any
(select badge,min(data_ora)from EntryExitLogs group by date(data_ora),badge))
union
(select * from EntryExitLogs where id in
(select id from EntryExitLogs where (badge,data_ora)= any
(select badge,max(data_ora)from EntryExitLogs group by date(data_ora),badge)))
order by id;
I think its better to make use of the ID column for selecting the rows, because the timestamp column contains duplicates.
You could use a join with subquery for badge 1 and badge 2
select t1.badge, min_dat, nax_date
from (
select badge, min_(data_ora) min_data
from my_table
where lettore = 1
group by badge
) t1
INNER JOIN (
select badge, max_(data_ora) max_data
from my_table
where lettore = 2
group by badge
) t2 ON t1.badge = t2.badge
Related
Somewhat new to SQL and I'm running into a bit of issue with a project. I have a table like this:
ID
subscription_ID
renewal_date
1
11
2022-01-01 00:00:00
2
11
2022-01-02 00:00:00
3
12
2022-01-01 00:00:00
4
12
2022-01-01 12:00:00
5
13
2022-01-01 12:00:00
6
13
2022-01-03 12:00:00
My goal is to return rows where the subscription_ID matches and the start_date is within or equal to a certain # of days (hours would work as well). For instance, I'd like rows where subscription_ID matches and the start_date is within or equal to 1 day such that my results from the table above would be:
ID
subscription_ID
renewal_date
1
11
2022-01-01 00:00:00
2
11
2022-01-02 00:00:00
3
12
2022-01-01 00:00:00
4
12
2022-01-01 12:00:00
Any assistance would be greatly appreciated--thanks!
If I understand correctly maybe you are trying something like:
select t.*
from test_tbl t
join ( SELECT subscription_id
, MAX(diff) max_diff
FROM
( SELECT x.subscription_id
, DATEDIFF(MIN(y.start_date),x.start_date) diff
FROM test_tbl x
JOIN test_tbl y ON y.subscription_id = x.subscription_id
AND y.start_date > x.start_date
GROUP BY x.subscription_id , x.start_date
) z
GROUP BY subscription_id
) as t1 on t.subscription_id=t1.subscription_id
where t1.max_diff<=1;
Result:
id subscription_id start_date
1 11 2022-01-01 00:00:00
2 11 2022-01-02 00:00:00
3 12 2022-01-01 00:00:00
4 12 2022-01-01 12:00:00
The subquery returns:
subscription_id max_diff
11 1
12 0
13 2
which is used on the where condition.
Demo
select a.no, a.Dtime,count(b.Dtime)+1 as Rank
from table1 a left
join table1 b on a.Dtime>b.Dtime and a.no=b.no
group by a.no,a.Dtime
order by a.no, a.Dtime
table1 Input:
NO Dtime
1 08:10:00
1 09:10:00
1 09:40:00
1 10:10:00
2 09:30:00
2 10:15:00
3 09:00:00
Output:
NO Dtime Rank
1 08:10:00 1
1 09:10:00 2
1 09:40:00 3
1 10:10:00 4
2 09:30:00 1
2 10:15:00 2
3 09:00:00 1
But I am looking for Output in mysql where table2 Rank links to table1 and table2 Dtime i.e. table1.Dtime>table2.time
table2 Input
NO Dtime
1 08:30:00
1 09:15:00
1 09:50:00
2 08:30:00
2 09:45:00
3 09:50:00
Output:
NO table1.Dtime Rank table2.Dtime
1 08:10:00 0 00:00:00
1 09:10:00 1 08:30:00
1 09:40:00 2 09:15:00
1 10:10:00 3 09:50:00
2 09:30:00 1 08:30:00
2 10:15:00 2 09:45:00
3 09:00:00 0 00:00:00
You can use the same approach with your initial query. Just left join to table2. To get the Dtime from table2 you can use a correlated subquery:
select a.no, a.Dtime,
count(b.Dtime) as Rank,
coalesce((select c.Dtime
from table2 as c
where c.no = a.no and a.Dtime > c.Dtime
order by c.Dtime desc limit 1), '00:00:00') as t2Dtime
from table1 a
left join table2 b on a.Dtime > b.Dtime and a.no = b.no
group by a.no,a.Dtime
order by a.no, a.Dtime
Demo here
i Need some help.. i have some case like this below
i have 2 table.. call ("in_table" and "out_table")
data "in_table" look like
stock_id item_id date qty_in
-----------------------------------------
1 11 2017-07-11 12
2 11 2017-07-11 10
3 12 2017-07-11 10
4 12 2017-07-19 10
And i have "out_table" is like
id_tr item_id date qty_out
-------------------------------------
1 11 2017-07-19 2
1 12 2017-07-19 1
2 11 2017-07-19 2
2 12 2017-07-19 1
And i want to combine the date and display all the data like this,
Update: the join is by item_id but i want to select by date
date item_id qty_in qty_out
---------------------------------------
2013-07-11 11 22 0
2013-07-11 12 10 0
2013-07-19 11 0 4
2013-07-19 12 10 2
Thank you for your help.
It looks like you need kind of a full outer join of two aggregate subqueries. But in your case I would get item_id and date in a union subquery (derived table) and the sums in correlated subqueries (subselect).
select item_id, date,
(select sum(qty_in) from in_table i where i.item_id = sub.item_id and i.date = sub.date) as qty_in,
(select sum(qty_out) from out_table o where o.item_id = sub.item_id and o.date = sub.date) as qty_out
from (
select item_id, date from in_table
union
select item_id, date from out_table
) sub
order by date, item_id
I have data like in this mysql table:
id customer_id date price
1 A 2014-01-01 4
2 A 2014-02-01 3
3 B 2014-03-01 2.5
4 B 2014-04-01 1
5 B 2014-05-01 5
6 C 2014-06-01 2
7 D 2014-07-01 2
8 D 2014-08-01 2.5
9 D 2014-09-01 1
I want to get the latest two dates for customer_id A, B and D. My result should be like this:
id customer_id date price
1 A 2014-01-01 4
2 A 2014-02-01 3
4 B 2014-04-01 1
5 B 2014-05-01 5
8 D 2014-08-01 2.5
9 D 2014-09-01 1
Any help is greatly appreciated.
One possible way :
SELECT *
FROM test s
WHERE (
SELECT COUNT(*)
FROM test f
WHERE f.customer_id = s.customer_id AND
f.`date` >= s.`date`
) <= 2
AND customer_id in('A','B','D');
[SQL Fiddle demo]
Try like this
select * from table where customer_id in('A','B','D') order by date desc limit 2
I've 4 tables as shown below
doctors
id name
------------
1 Mathew
2 Praveen
3 Rosie
4 Arjun
5 Denis
doctors_appointments
id doctors_id patient_name contact date status
--------------------------------------------------------------------------------------
1 5 Nidhin 9876543210 2012-12-10 15:39:41 Registered
2 5 Sunny 9876543210 2012-12-18 15:39:48 Registered
3 5 Mani 9876543210 2012-12-12 15:39:57 Registered
4 2 John 9876543210 2012-12-24 15:40:09 Registered
5 4 Raj 9876543210 2012-12-05 15:41:57 Registered
6 3 Samuel 9876543210 2012-12-14 15:41:33 Registered
7 2 Louis 9876543210 2012-12-24 15:40:23 Registered
8 1 Federick 9876543210 2012-12-28 15:41:05 Registered
9 2 Sam 9876543210 2012-12-12 15:40:38 Registered
10 4 Sita 9876543210 2012-12-12 15:41:00 Registered
doctors_dutyplan
id doctor_id weeks time no_of_patients
------------------------------------------------------------------
1 1 3,6,7 9:00am-1:00pm 10
2 2 3,4,5 1:00pm-4:00pm 7
3 3 3,6,7 10:00am-2:00pm 10
4 4 3,4,5,6 8:30am-12:30pm 12
5 5 3,4,5,6,7 9:00am-4:00pm 30
emp_leave
id empid leavedate
--------------------------------
1 2 2012-12-05 14:42:36
2 2 2012-12-03 14:42:59
3 3 2012-12-03 14:43:06
4 3 2012-12-06 14:43:14
5 5 2012-12-04 14:43:24
My task is to find all the days in a month in which the doctor is available excluding the leave dates.
My query what is wrote is given below:
SELECT DATE_ADD( '2012-12-01', INTERVAL
ROW DAY ) AS Date,
ROW +1 AS DayOfMonth
FROM (
SELECT #row := #row +1 AS
ROW FROM (
SELECT 0
UNION ALL SELECT 1
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
)t1, (
SELECT 0
UNION ALL SELECT 1
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
)t2, (
SELECT #row := -1
)t3
LIMIT 31
)b
WHERE DATE_ADD( '2012-12-01', INTERVAL
ROW DAY )
BETWEEN '2012-12-01'
AND '2012-12-31'
AND DAYOFWEEK( DATE_ADD( '2012-12-01', INTERVAL
ROW DAY ) ) =2
AND DATE_ADD( '2012-12-01', INTERVAL
ROW DAY ) NOT
IN (
SELECT DATE_FORMAT( l.leavedate, '%Y-%m-%d' ) AS date
FROM doctors_dutyplan d
LEFT JOIN emp_leave AS l ON d.doctor_id = l.empid
WHERE doctor_id =2
)
This works fine for all doctors who took any leave in a particular day in a month (here in the example it is Decemeber 2012). and the result for the above query is shown below:
Date DayOfMonth
-----------------------
2012-12-10 10
2012-12-17 17
2012-12-24 24
2012-12-31 31
But on the other hand for the doctors who didn't took any leave , for that my query is showing empty table, example for the doctor Mathew whose id is 1, my query returns an empty result
can anyone please tell a solution for this problem.
Thanks in advance.
Your query is large, but this part looks fishy:
NOT IN (
SELECT DATE_FORMAT( l.leavedate, '%Y-%m-%d' ) AS date
FROM doctors_dutyplan d
LEFT JOIN emp_leave AS l ON d.doctor_id = l.empid
WHERE doctor_id =2
The left join means a null would be returned for doctor 1. Now, col1 not in (null) does not behave as you may expect. It translates to:
col1 <> null
Which is never true. You could solve this by changing the left join to an inner join, so an empty set instead of null is returned for a doctor without leave.