Dobře, tak to zkusíme a uvidíme, jestli to funguje.
Toto je schéma, se kterým mám pár věcí. Je to velmi jednoduché, ale podporuje váš případ použití.
CREATE TABLE employees (
id int unsigned auto_increment,
name varchar(255),
PRIMARY KEY(id)
);
CREATE TABLE leave_type (
id int unsigned auto_increment,
name varchar(255),
PRIMARY KEY(id)
);
CREATE TABLE leave_log (
id int unsigned auto_increment,
leave_type_id int unsigned,
employee_id int unsigned,
is_full_day int unsigned,
is_half_day int unsigned,
PRIMARY KEY(id)
);
Některá testovací data ...
INSERT INTO employees VALUES (14, 'Lisa'), (15, 'Homer'), (13, 'Bart');
INSERT INTO leave_type VALUES (1, 'Annual'), (2, 'Unpaid'), (3, 'Exam');
INSERT INTO leave_log VALUES (NULL, 3, 14, 1, 0), (NULL, 1, 14, 1, 0), (NULL, 1, 14, 0, 1), (NULL, 1, 14, 0, 1);
INSERT INTO leave_log VALUES (NULL, 2, 15, 0, 1);
INSERT INTO leave_log VALUES (NULL, 3, 13, 1, 0), (NULL, 1, 13, 1, 0);
Nesoustřeďte se příliš na názvy a definice sloupců, schéma jsem vůbec nevylepšoval, protože o vaší aplikaci nevím dost, abych to udělal.
Jakmile je schéma vytvořeno a jsou tam data, tento docela jednoduchý dotaz by měl dělat to, co chcete.
SELECT e.name, SUM(annual.is_half_day), SUM(unpaid.is_half_day), SUM(exam.is_half_day),
SUM(annual.is_full_day), SUM(unpaid.is_full_day), SUM(exam.is_full_day)
FROM employees e
LEFT JOIN leave_log annual ON annual.leave_type_id = 1 AND annual.employee_id = e.id
LEFT JOIN leave_log unpaid ON unpaid.leave_type_id = 2 AND unpaid.employee_id = e.id
LEFT JOIN leave_log exam ON exam.leave_type_id = 3 AND exam.employee_id = e.id
GROUP BY e.id
Podívejte se a uvidíte, co si myslíte. Je to pravděpodobně vysoce výkonná nebo silně zatížená aplikace?
UPRAVIT
Tento dotaz je složitější a pravděpodobně by měl určité nedostatky ve výkonu, ale může být přesnější.
SELECT e.name, e.id,
IFNULL(annual_half.total, 0) annual_half,
IFNULL(unpaid_half.total, 0) unpaid_half,
IFNULL(exam_half.total, 0) exam_half,
IFNULL(annual_full.total, 0) annual_full,
IFNULL(unpaid_full.total, 0) unpaid_full,
IFNULL(exam_full.total, 0) exam_full
FROM employees e
LEFT JOIN ( SELECT SUM(is_full_day) as total, employee_id, leave_type_id FROM leave_log WHERE is_full_day = 1 AND leave_type_id = 1 GROUP BY 3, 2) annual_full ON annual_full.employee_id = e.id
LEFT JOIN ( SELECT SUM(is_full_day) as total, employee_id, leave_type_id FROM leave_log WHERE is_full_day = 1 AND leave_type_id = 2 GROUP BY 3, 2) unpaid_full ON unpaid_full.employee_id = e.id
LEFT JOIN ( SELECT SUM(is_full_day) as total, employee_id, leave_type_id FROM leave_log WHERE is_full_day = 1 AND leave_type_id = 3 GROUP BY 3, 2) exam_full ON exam_full.employee_id = e.id
LEFT JOIN ( SELECT SUM(is_half_day) as total, employee_id, leave_type_id FROM leave_log WHERE is_half_day = 1 AND leave_type_id = 1 GROUP BY 3, 2) annual_half ON annual_half.employee_id = e.id
LEFT JOIN ( SELECT SUM(is_half_day) as total, employee_id, leave_type_id FROM leave_log WHERE is_half_day = 1 AND leave_type_id = 2 GROUP BY 3, 2) unpaid_half ON unpaid_half.employee_id = e.id
LEFT JOIN ( SELECT SUM(is_half_day) as total, employee_id, leave_type_id FROM leave_log WHERE is_half_day = 1 AND leave_type_id = 3 GROUP BY 3, 2) exam_half ON exam_half.employee_id = e.id
GROUP BY 1;