Assuming I have 3 tables:
leave_type:
id | name
1 | maternity leave
2 | Medical leave
3 | Casual Leave
4 | Sick Leave
5 | honeymoon Leave
employee
id | name
4 | Employee 1
7 | Employee 2
employee_leave_blance
id | employee_id | year | leave_type_id | val
1 | 4 | 2015 | 1 | 9
2 | 4 | 2015 | 2 | 5
3 | 7 | 2015 | 1 | 10
4 | 4 | 2015 | 3 | 4
Here, employee_leave_blance.leave_type_id = leave_type.id
Now I want to get all Leave Type values for all employee.
Let me give an example: I want to get output for employee_id = 4, 7
employee_id | name | val
4 | maternity leave | 9
4 | Medical leave | 5
4 | Casual Leave | 4
4 | Sick Leave | 0
4 | honeymoon Leave | 0
7 | maternity leave | 10
7 | Medical leave | 0
7 | Casual Leave | 0
7 | Sick Leave | 0
7 | honeymoon Leave | 0
My query
SELECT
lt.name, ifnull(el.val,0) as val , el.employee_id
FROM leave_type AS lt
LEFT JOIN employee_leave_balance AS el ON el.leave_type_id = lt.id
AND
el.year = YEAR(CURDATE()) GROUP BY el.employee_id
You can do it this way:
SELECT employee_id,leave_name,IFNULL(val,0) as val
FROM
(SELECT e.id as employee_id,l.id as lid,l.name as leave_name
FROM employee e CROSS JOIN leave_type l) as T1 LEFT JOIN
(SELECT val,employee_id as eid,leave_type_id as lid
FROM employee_leave_blance elb) as T2 ON T1.employee_id=T2.eid AND T1.lid=T2.lid
ORDER BY employee_id asc,val desc
Result:
employee_id leave_name val
--------------------------------
4 maternity leave 9
4 Medical leave 5
4 Casual Leave 4
4 Sick Leave 0
4 honeymoon Leave 0
7 maternity leave 10
7 Casual Leave 0
7 honeymoon Leave 0
7 Sick Leave 0
7 Medical leave 0
Sample result in SQL Fiddle.
Try this code
SELECT * FROM leave_type
INNER JOIN employee_leave_blance on leave_type.id = employee_leave_blance.leave_type_id
INNER JOIN `employee on employee.id = employee_leave_blance.employee_id
i have update my answer
Update :
select lt.name,e.id,elb.val from
leave_type as lt, employee as e,employee_leave_blance as elb
where e.id = elb.employee_id and lb.leave_type_id = lt.id
and elb.year= YEAR(CURDATE()) order by (e.id)
Sample on SQL Fiddle
run this query.i haven't tried it but i hope it will work fine
select * from leave_type as lt, employee as e, employee_leave_balance as elb
where e.id = elb.employee_id and elb.leave_type_id = lt.id and e.id = $id
Related
My 3 MYSQL tables are as follows:
Table 1: citizen
=============================
ID | Name | Sex | Address |
=============================
5 | James | Male | India
6 | Shella|Female | India
7 | Jan | Male | NY
8 | May | Female | USA
==============================
Table 2: benefits
==========================
ID| benefits
==========================
1 | SSS
2 | Coco Life
3 | PhiHealth
4 | Sunlife
==========================
Table 3: pensioners
============================
ID| benefits_ID | citizen_ID
============================
1 | 1 | 5
2 | 2 | 6
3 | 1 | 7
4 | 4 | 7
==========================
I want to display that looks like this:
====================================================================
Address | Total Citizen | Male | Female | SSS | Coco Life | Others |
====================================================================
India | 2 | 1 | 1 | 1 | 1 | 0 |
NY | 1 | 1 | 0 | 1 | 0 | 1 |
USA | 1 | 0 | 1 | 0 | 0 | 0 |
==================================================================
Anybody can give me a hint on how to do this?
You can do a Left Join from the Address table to the benefits table, via pensioners table, using the appropriate relationships. Left join will allows us to consider a Address even when there is no corresponding benefits entry for any of its citizens.
In order to count total citizens, male count and female count, you now need to use COUNT(DISTINCT ID) after the join. As Joining may create duplicate rows, as a citizen may have more than one benefits.
Also, in order to count "Other" benefits, we need to ensure that the benefit IS NOT NULL and it is NOT IN ('SSS', 'Coco Life').
In multi-table queries, it is advisable to use Aliasing for Code clarity (readability) and avoiding ambiguous behaviour.
SELECT
c.Address,
COUNT(DISTINCT CASE WHEN c.Sex = 'Male' THEN c.ID END) AS male_cnt,
COUNT(DISTINCT CASE WHEN c.Sex = 'Female' THEN c.ID END) AS female_cnt,
COUNT(DISTINCT c.ID) AS total_citizen_cnt,
COUNT(CASE WHEN b.benefits = 'SSS' THEN 1 END) AS SSS_cnt,
COUNT(CASE WHEN b.benefits = 'Coco Life' THEN 1 END) AS Coco_Life_cnt,
COUNT(CASE WHEN b.benefits IS NOT NULL AND
b.benefits NOT IN ('SSS', 'Coco Life') THEN 1 END) AS Others_cnt
FROM citizen AS c
LEFT JOIN pensioners AS p
ON p.citizen_ID = c.ID
LEFT JOIN benefits AS b
ON b.ID = p.benefits_ID
GROUP BY c.Address
I need to get all IDs from table A where all the Expiry date from Table B (INNER JOIN ID = A_ID) are < today (2018-06-29) but i'm not sure and a bit confusing for the query.
Based on my example (2018-06-29) i need to retrieve only Name-4 because ALL Expiry date from Table B are < 2018-06-29
Table A
ID | Name |
-------------
1 | Name-1
2 | Name-2
3 | Name-3
4 | Name-4
5 | Name-5
6 | Name-6
7 | Name-7
Table B
ID | A_ID | Expiry
-----------------------
1 | 1 | 2018-06-29
2 | 2 | 2018-07-29
3 | 2 | 2018-06-29
4 | 3 | 2018-07-29
5 | 3 | 2018-04-29
6 | 4 | 2018-05-29
7 | 4 | 2018-04-29
8 | 6 | 2018-09-29
9 | 6 | 2018-10-29
You are correct that you need both the GROUP BY and the HAVING clauses. Since you require that all expiry dates for a matching A_ID are less than a given date, you must check the MAX() expiry for that grouping.
SELECT ta.* FROM tableA ta JOIN tableB tb ON ta.ID = tb.A_ID
GROUP BY ta.id
HAVING MAX(Expiry) < '2018-06-20';
DEMO
Facing issue in mysql query, tried with mysql join but not getting expected output.
I want all class, all student record with total ratingscore.Each Class has Many Student. Student has Many or none scholarship
Class table looks like this
+---------------------+
| id classname |
+---------------------+
| 1 10 |
| 2 11 |
| 3 12 |
+---------------------+
Student table looks like, classid is foreign key
+------------------------------------+
| id classid studentname |
+------------------------------------+
| 1 1 xembine |
| 2 1 denial |
| 3 2 suzone |
| 4 3 rosh |
| 5 2 broad |
| 6 1 bell |
| 7 3 martin |
| 8 1 jroff |
+------------------------------------+
rating table looks like, studentid is foreign key
+------------------------------------+
| id studentid ratingscore |
+------------------------------------+
| 1 1 4000 |
| 2 1 10000 |
| 3 5 20000 |
| 4 2 1000 |
| 5 6 2222 |
| 6 1 5000 |
| 7 6 12000 |
| 8 3 3800 |
| 9 5 7500 |
+------------------------------------+
Here : No student from class 3, got any ratingscore yet.so need that student has zero ratingscore.
Expected Output:-
+-------------------------------------------------------------+
| studentname studentid classid classname ratingscore |
+-------------------------------------------------------------+
| xembine 1 1 10 19000 |
| denial 2 1 10 1000 |
| suzone 3 2 11 3800 |
| rosh 4 3 12 0 |
| broad 5 2 11 27500 |
| bell 6 1 10 2222 |
| martin 7 3 12 0 |
| jroff 8 1 10 0 |
+-------------------------------------------------------------+
select s.studentname, s.id as studentid,s.classid,c.classname,sum(ifnull(r.ratingscore,0)) as ratingscore from student s
join class c on c.id=s.classid
left outer join rating r on r.studentid=s.id
group by s.studentname,r.studentid,s.classid,c.classname
Have you try this ?
SELECT s.studentname, s.studentid, c.classid, c.classname, SUM(r.ratingscore)
FROM student as s
INNER JOIN class c on c.classid = s.classid
LEFT OUTER JOIN ratingscore rs ON s.studentid = rs.studentid
GROUP BY s.studentname, s.studentid, c.classid, c.classname
ORDER BY s.studentid
If there is student without class, you have to change inner join to left outer join
SELECT s.studentname AS studentname, s.id AS studentid, c.id AS classid, c.classname AS classname, SUM(r.ratingscore) AS ratingscore
FROM student AS s
INNER JOIN class AS c ON c.id = s.classid
LEFT JOIN rating r ON r.studentid = s.id
GROUP BY s.id
ORDER BY s.id
I have workshops that have manufacturers, one workshop can have many manufacturers, but only one official. I want to get all workshops that have manufacturer 22 but if they have same vat only get workshop who manufacturer is offical
I have 2 tables, first workshop
id | name | vat
-------------------------
1 | name 1 | B12
2 | name 2 | B12
3 | name 3 | B12
4 | name 4 | E98
5 | name 5 | A99
second workshop_manufacturer
id | workshop_id | manufacturer_id | official
----------------------------------------------
1 | 1 | 22 | 0
2 | 2 | 22 | 0
3 | 3 | 22 | 1
4 | 4 | 22 | 0
5 | 5 | 22 | 1
5 | 5 | 23 | 0
5 | 5 | 24 | 0
I want to get unique workshops (group by vat) but I want to get the official one (official=1) if there are many workshop with same vat who work with this manufacturer.
If I do this query:
SELECT t1.*,t2.* FROM workshop t1
INNER JOIN workshop_manufacturer t2 ON t1.id=t2.workshop_id
WHERE t2.manufacturer.id = 22
GROUP bY t1.vat
I get this:
id | name | vat | official | manufacturer_id
-----------------------------------------------
1 | name 1 | B12 | 0 | 22
4 | name 4 | E98 | 0 | 22
5 | name 5 | A99 | 1 | 22
and I want this:
id | name | vat | official | manufacturer_id
-----------------------------------------------
3 | name 3 | B12 | 1 | 22
4 | name 4 | E98 | 0 | 22
5 | name 5 | A99 | 1 | 22
All the workshops who are official and non official but giving priority that ones who are official
This is a prioritization, not an aggregation. But it is rather complicated.
The following gets the ids for the workshops for each "vat":
select w.vat, max(case when w.official = 1 then w.id end) as official_id,
max(w.id) as max_id
from workshop_manufacturer wm join
workshop w
on w.id = wm.workshop_id
group by w.vat;
There are two ids, one if official is available, and another for the maximum id.
You can now use this in a join to get the rest of the fields:
select w.workshop_id, w.name, w.vat,
(official_id is not null) as official
from (select w.vat, max(case when w.official = 1 then w.id end) as official_id,
max(w.id) as max_id
from workshop_manufacturer wm join
workshop w
on w.id = wm.workshop_id
group by w.vat
) v join
workshop w
on w.id = coalesce(official_id, max_id);
Try this.
SELECT t1.*,t2.* FROM workshop t1
INNER JOIN workshop_manufacturer t2 ON t1.id=t2.workshop_id
GROUP bY t1.vat having t2.official = 1
My MySQL DB looks like this
**table_schools**
id | name
1 | school_1
2 | school_2
**table_classes**
id | class | school_id
1 | a | 1
2 | b | 1
3 | c | 2
4 | d | 2
5 | e | 2
**table_students**
id | name | class_id
1 | Nick | 1
2 | Tom | 2
3 | Kevin | 3
4 | Jane | 4
5 | Mark | 5
6 | Tim | 5
7 | Lynn | 5
I would like to have an output like this:
school_name | class_count | student_count
school_1 | 2 | 2
school_2 | 3 | 5
Is there a way to do this in ONE sql query? And how?
SELECT s.name, COUNT(DISTINCT c.id) AS classes, COUNT(st.id) AS students
FROM table_schools s
LEFT JOIN
table_classes c
ON c.school_id = s.id
LEFT JOIN
table_students st
ON st.class_id = c.id
GROUP BY
s.id
SELECT table_schools.name, COUNT(table_classes.name) AS classes, COUNT(table_students.id) AS students
FROM table_schools
LEFT JOIN table_classes ON table_schools.id = table_classes.school_id
LEFT JOIN table_students ON table_students.class_id = table_classes.id
GROUP BY table_schools.id, table_classes.id
ORDER BY table_schools.name