У меня есть 3 таблицы: проекты, сотрудники и назначения. Сотрудники назначены на разные проекты, и проекты могут занять некоторое время. Мне нужно найти сотрудника, который будет свободен в определенный день (не будет назначен проект).
CREATE TABLE Employee (
id NUMBER(10) NOT NULL PRIMARY KEY,
name VARCHAR2(50) NOT NULL
);
CREATE TABLE Projects (
id NUMBER(10) NOT NULL PRIMARY KEY,
name VARCHAR(200) NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL
);
INSERT INTO
Employee(id, name) VALUES (1, 'Joe Doe');
INSERT INTO
Employee(id, name) VALUES (2, 'Alex Doe');
INSERT INTO
Projects(id, name, start_date, end_date)
VALUES (1, 'AAA',
TO_DATE('2020/12/30 00:00:00', 'yyyy/mm/dd hh24:mi:ss'),
TO_DATE('2021/06/30 00:00:00', 'yyyy/mm/dd hh24:mi:ss'));
INSERT INTO
Projects(id, name, start_date, end_date)
VALUES (2, 'BBB',
TO_DATE('2020/11/30 00:00:00', 'yyyy/mm/dd hh24:mi:ss'),
TO_DATE('2021/03/30 00:00:00', 'yyyy/mm/dd hh24:mi:ss'));
INSERT INTO
Projects(id, name, start_date, end_date)
VALUES (3, 'CCC',
TO_DATE('2020/11/10 00:00:00', 'yyyy/mm/dd hh24:mi:ss'),
TO_DATE('2020/11/30 00:00:00', 'yyyy/mm/dd hh24:mi:ss'));
CREATE TABLE Assignments (
id NUMBER(10) NOT NULL PRIMARY KEY,
employee_id NUMBER(10) NOT NULL,
project_id NUMBER(10) NOT NULL,
CONSTRAINT employee_fk FOREIGN KEY (employee_id) REFERENCES Employee(id),
CONSTRAINT project_fk FOREIGN KEY (project_id) REFERENCES Projects(id)
);
INSERT INTO Assignments(id, project_id, employee_id)
VALUES (1, 1, 1);
INSERT INTO Assignments(id, project_id, employee_id)
VALUES (2, 1, 2);
INSERT INTO Assignments(id, project_id, employee_id)
VALUES (3, 2, 1);
INSERT INTO Assignments(id, project_id, employee_id)
VALUES (4, 3, 1);
Я знаю, как проверять людей и их проекты, но мне нужна помощь с условием месяца и дня. Допустим, этот конкретный день 24 марта. Я придумал что-то вроде этого, но это не то, что я хочу - потому что, думаю, мне нужно как-то проверить, не находится ли свободный день во времени продолжительности проекта - я прав? Как это сделать?
SELECT Employee.name, Projects.name
FROM Assignments
INNER JOIN Employee ON Employee.id = Assignments.employee_id
INNER JOIN Projects ON Projects.id = Assignments.project_id
WHERE EXTRACT(month FROM Projects.start_date) < 3 AND
EXTRACT(day FROM Projects.start_date) > 24
GROUP BY Employee.name, Projects.name;
Вы можете использовать литерал DATE
, чтобы создать дату и проверить, свободен ли сотрудник в конкретную дату, используя EXISTS
следующим образом:
SELECT DISTINCT Employee.name FROM Assignments
INNER JOIN Employee ON Employee.id = Assignments.employee_id
WHERE NOT EXISTS (SELECT 1 FROM Projects
WHERE Projects.id = Assignments.project_id
AND DATE '2020-03-24'
BETWEEN Projects.START_date AND Projects.end_date);
Вы также можете использовать GROUP BY
и HAVING
следующим образом:
SELECT Employee.name FROM Assignments
INNER JOIN Employee ON Employee.id = Assignments.employee_id
INNER JOIN Projects ON Projects.id = Assignments.project_id
GROUP BY Employee.name
HAVING COUNT (CASE WHEN DATE '2020-03-24'
BETWEEN Projects.START_date
AND Projects.end_date
THEN 1 END) = 0