У меня есть эти таблицы:
CREATE TABLE Client
(
client_id NUMBER(10) NOT NULL PRIMARY KEY,
name VARCHAR(50) NOT NULL,
address VARCHAR(50) NOT NULL
);
CREATE TABLE Projects
(
project_id NUMBER(10) NOT NULL PRIMARY KEY,
project_name VARCHAR(200) NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
client_id NUMBER(10) NOT NULL,
CONSTRAINT client_fk
FOREIGN KEY (client_id) REFERENCES Client(client_id)
);
INSERT INTO Client (client_id, name, address)
VALUES (1, 'Joe Doe', '11 Henry Smith St.Chelsea, MA 02150');
INSERT INTO Client (client_id, name, address)
VALUES (2, 'James Doe', '74 East Sierra Ave. Batavia, OH 45103');
INSERT INTO Projects (project_id, project_name, start_date, end_date, client_id)
VALUES (1, 'YYY', TO_DATE('2020/12/03 21:02:44', 'yyyy/mm/dd hh24:mi:ss'),
TO_DATE('2020/12/30 21:02:44', 'yyyy/mm/dd hh24:mi:ss'), 1);
INSERT INTO Projects (project_id, project_name, start_date, end_date, client_id)
VALUES (2, 'XXX', TO_DATE('2020/11/01 21:02:44', 'yyyy/mm/dd hh24:mi:ss'),
TO_DATE('2020/12/30 21:02:44', 'yyyy/mm/dd hh24:mi:ss'), 2);
Я хочу выбрать проект с максимальной продолжительностью вместе с именем сотрудника.
Я написал этот оператор SQL:
SELECT
p.project_name, c.name,
FROM
Projects p, Client c
WHERE
p.client_id = c.client_id
AND max_time = (SELECT MAX(p.end_date - p.start_date) FROM Projects p);
Но я получаю сообщение об ошибке
ORA-00936: отсутствует выражение
Вот код: http://sqlfiddle.com/#!4/00720/1
Как насчет того, чтобы просто использовать fetch first
?
SELECT p.project_name, c.name
FROM Projects p JOIN
Client c
ON p.client_id = c.client_id
ORDER BY (p.estimated_end_date - p.project_start_date)
FETCH FIRST 1 ROW ONLY;
Здесь db<>рабочий пример. Версия Oracle на SQLFiddle устарела и не поддерживает FETCH FIRST
.
Хорошо, спасибо, но все та же ошибка: sqlfiddle.com/#!4/00720/5
@мазикс. . . Я включил скрипку db<>, потому что эта версия устарела.
У вас есть сбои в именах столбцов в скрипке и нежелательная запятая после c.name
.
Учитывать:
SELECT p.project_name, c.name
FROM Projects p
INNER JOIN Client c ON p.client_id = c.client_id
WHERE (p.end_date - p.start_date) = (
SELECT MAX(end_date - start_date) FROM Projects
);
В Oracle 12 или выше вы также можете использовать предложение FETCH
, как предложил Гордон Линофф. Я бы рекомендовал WITH TIES
сделать запрос эквивалентным вашему исходному коду:
SELECT p.project_name, c.name
FROM Projects p
INNER JOIN Client c ON p.client_id = c.client_id
ORDER BY p.end_date - p.start_date DESC
FETCH FIRST ROW WITH TIES
В более старых версиях вместо этого можно использовать RANK()
:
SELECT *
FROM (
SELECT p.project_name, c.name,
RANK() OVER(ORDER BY p.end_date - p.start_date DESC) as rn
FROM Projects p
INNER JOIN Client c ON p.client_id = c.client_id
) t
WHERE rn = 1
JOIN
в стандарте SQL ANSI-92 (более 25 лет назад) и его использование обескуражен