MySQL: Finding the missing values from tables - mysql

I have two different tables:
checkin_out consists of two fields: emp_code, checked_date
temp_days consists of two fields: id, date_value
Table checkin_out has following data:
emp_code | checked_date
-----------------------
001 2012-11-01
001 2012-11-02
001 2012-11-03
002 2012-11-01
003 2012-11-01
003 2012-11-02
While table temp_days has following data:
id | date_value
-----------------
1 2012-11-01
2 2012-11-02
3 2012-11-03
4 2012-11-04
5 2012-11-05
From the above tables, I need to show the missing dates in the table temp_days; I need to query to get a result as follow:
emp_code | date_value
-----------------------
001 2012-11-04
001 2012-11-05
002 2012-11-02
002 2012-11-03
002 2012-11-04
002 2012-11-05
003 2012-11-03
003 2012-11-04
003 2012-11-05
If anyone could help, please! Thanks!

The below works for a more complex data set with multiple emp_codes.
SELECT alldays.emp_code, alldays.date_value
FROM (
SELECT date_value, emp_code
FROM temp_days
CROSS JOIN checkin_out
GROUP BY date_value, emp_code
) alldays
LEFT JOIN checkin_out C
ON alldays.date_value = C.checked_date
AND alldays.emp_code = C.emp_code
WHERE C.emp_code IS NULL

SELECT c.emp_code, a.date_value
FROM temp_days a
LEFT JOIN checkin_out b
ON a.date_value = b.checked_date
CROSS JOIN
(
SELECT emp_code
FROM checkin_out
GROUP BY emp_code
) c
WHERE b.emp_code IS NULL
SQLFiddle Demo

Related

Joining multiple tables with n to m relationships

I need to join three tables(from a MySQL database) where the second one is the link between the others.
The problem is tables 1 and 2 have multiple values (by Id or FeeId) and I cannot group in order to create a table like that:
EXPECTED RESULT TABLE
PaymentId
Amount
FeeCost
001
50
6
002
100
10
003
85
8
T1
PaymentId
Amount
0001
50
0002
75
0002
25
0003
20
0003
15
0003
50
T2
PaymentId
FeeId
001
AAA
002
AAB
003
AAC
T3
FeeId
FeeCost
AAA
2
AAB
4
AAC
3
AAC
2
AAC
3
AAA
2
AAB
4
AAA
2
AAB
2
I tried with multiple codes like that but I cannot join in a correct way
SELECT PaymentId, SUM(Amount), SUM(FeeCost)
FROM T2
INNER JOIN T1 ON T1.paymentId = T2.paymentId
INNER JOIN T3 ON T3.FeeId = T2.FeeId
GROUP BY T2.paymentId

How to join based on max timestamp in SQL?

So I have a df like this:
ID fruit
001 grapes
002 apples
002 mangos
003 bananas
004 oranges
004 grapes
And I want to join the following onto it:
ID store_time
001 2021-04-02 03:02:00.321
002 2021-04-02 02:02:00.319
002 2021-04-03 12:02:00.319
002 2021-04-04 13:02:00.312
003 2021-04-02 19:02:00.313
004 2021-04-02 15:02:00.122
004 2021-04-01 11:02:00.121
So all I want to do is join based on just the most recent timestamp. So leave the others behind and have only the number of rows as there are in the fruit df.
Final output:
ID fruit timestamp
001 grapes 2021-04-02 03:02:00.321
002 apples 2021-04-04 13:02:00.312
002 mangos 2021-04-04 13:02:00.312
003 bananas 2021-04-02 19:02:00.313
004 oranges 2021-04-02 15:02:00.122
004 grapes 2021-04-02 15:02:00.122
Aggregate in the 2nd table to get the most recent store_time for each ID and then join to the 1st table:
SELECT t1.ID, t1.fruit, t2.timestamp
FROM table1 t1
LEFT JOIN (
SELECT ID, MAX(store_time) timestamp
FROM table2
GROUP BY ID
) t2 ON t2.ID = t1.ID
I used a LEFT join just in case table2 does not contain all the IDs of table1.
If this is not the case then you can change it to an INNER join.
you need a subquery for max tme stamp
select a.id, a.fruit, b.max_time
from my_table_fruit a
inner join (
select id, max(store_time) max_time
from my_table_time
) b on b.id = a.id

MySql select all rows in one table based on MAX value in another table

I want to be able to get all the data from table 1 and table 3 below but in addition to this I also want to get the latest application stage from table 2. The latest application stage is determined by getting the max stage_date for each application.
Table 1: applications
id | applicant_id | col_x | col_y | col_z
-----------------------------------------
10 300 a b c
11 310 a b c
12 320 a b c
13 330 a b c
14 340 a b c
Table 2: application_progress
id | application_id | application_stage | stage_date | stage_notes
------------------------------------------------------------------
1 10 DRAFT 2013-01-01 (NULL)
2 10 APPLICATION 2013-01-14 (NULL)
3 10 PHASE1 2013-01-30 (NULL)
4 11 DRAFT 2013-01-01 (NULL)
4 12 DRAFT 2013-01-01 (NULL)
5 13 DRAFT 2013-01-01 (NULL)
6 14 DRAFT 2013-01-01 (NULL)
7 14 APPLICATION 2013-01-14 (NULL)
EDIT: third table
Table 3: applicants
id | applicant_name | applicant_address | programme_id
------------------------------------------------------
300 Applicant 1 abc 1
310 Applicant 2 xyz 2
320 Applicant 3 xyz 2
330 Applicant 4 xyz 2
340 Applicant 5 xyz 2
Returned data set
applicant_id | applicant_name | current_stage
---------------------------------------------------------
300 Applicant 1 PHASE1
310 Applicant 2 DRAFT
320 Applicant 3 DRAFT
330 Applicant 4 DRAFT
340 Applicant 5 APPLICATION
Am struggling with this one and would appreciate any help.
PS. Tried to put an example of sqlfiddle but it's down at the minute. I'll update this with the sqlfiddle when it's back up if haven't had an answer before this.
You can do this with a correlated subquery:
select a.*,
(select application_stage
from application_progress ap
where ap.application_id = a.id
order by stage_date desc
limit 1
) MostRecentStage
from applications a;
EDIT:
You can joining in the applicant data with something like this::
select a.*, aa.*,
(select application_stage
from application_progress ap
where ap.application_id = a.id
order by stage_date desc
limit 1
) MostRecentStage
from applications a join
applicant aa
on a.applicant_id = aa.id;

Getting Max date from multiple table after INNER JOIN

I have two following tables
table 1)
ID | HOTEL ID | NAME
1 100 xyz
2 101 pqr
3 102 abc
table 2)
ID | BOOKING ID | DEPARTURE DATE | AMOUNT
1 1 2013-04-12 100
2 1 2013-04-14 120
3 1 2013-04-9 90
4 2 2013-04-14 100
5 2 2013-04-18 150
6 3 2013-04-12 100
I want to get reault in mysql such that it take the row from table two with MAX DEPARTURE DATE.
ID | BOOKING ID | DEPARTURE DATE | AMOUNT
2 1 2013-04-14 120
5 2 2013-04-18 150
6 3 2013-04-12 100
SELECT b.ID,
b.BookingID,
a.Name,
b.departureDate,
b.Amount
FROM Table1 a
INNER JOIN Table2 b
ON a.ID = b.BookingID
INNER JOIN
(
SELECT BookingID, MAX(DepartureDate) Max_Date
FROM Table2
GROUP BY BookingID
) c ON b.BookingID = c.BookingID AND
b.DepartureDate = c.Max_date
SQLFiddle Demo
Well,
SELECT * FROM `table2` ORDER BY `DEPARTURE_DATE` DESC LIMIT 0,1
should help

Datediff in date format

I have 2 tables with structure as
Emp Table
id name
001 Smith
002 Jerry
Leave
sr.no reason from_date to_date request_by status
1 PL 2011-12-11 2011-12-15 001 Declined
2 PL 2011-11-13 2011-11-13 001 Approved
3 PL 2011-10-02 2011-10-05 002 Declined
Now I have written this query
select DATEDIFF(Leave.from_date,Leave.to_date)as cdate,
Emp.id as emp
from Leave left join Emp
on Leave.request_by=Emp.id
gives me difference between these 2 dates like...
cdate emp
-4 001
0 001
-3 002
The first thing about this output difference between '2011-12-11 & 2011-12-15 ' need to be 5 as for 5 consecutive days employee is absent. That we achieve it.
But I need this cdate in date format like('%Y%m%d') and + if date difference is say -4 then 4 records should be displayed for that.
So I want to write a query which gives output like this......
cdate emp
2011-12-11 001
2011-12-12 001
2011-12-13 001
2011-12-14 001
2011-12-15 001
2011-11-13 001
2011-10-02 002
2011-10-03 002
2011-10-04 002
2011-10-05 002
So can anybody tell me what how should I need to write my query to get this output?
Try this query -
CREATE TABLE temp_days(d INT(11));
INSERT INTO temp_days VALUES
(0),(1),(2),(3),(4),(5),
(6),(7),(8),(9),(10),
(11),(12),(13),(14),(15); -- maximum day difference, add more days here
SELECT l.from_date + INTERVAL td.d DAY cdate, e.id emp
FROM
`leave` l
LEFT JOIN Emp e
ON l.request_by = e.id
JOIN temp_days td
ON DATEDIFF(l.to_date, l.from_date) >= td.d
ORDER BY
e.id