Я сейчас работаю над проектом, и мне нужно сделать запрос к моей БД через SQL * PLUS.
Вот что я пытаюсь сделать. Я хочу получить таблицу, в которой я получаю имя и фамилию профессора с этими условиями (мне нужно проверить первое условие, а затем другое):
(Во-первых) На сессии (скажем, 12 004) профессор преподавал эти два курса, INF3180 и INF2110.
(Второй) На другой сессии, 32003, профессор преподавал эти два курса, INF1130 и INF1110.
Вот код, который создал БД:
CREATE TABLE Professor
(professorCode CHAR(5) NOT NULL,
lastName VARCHAR(10) NOT NULL,
firstName VARCHAR(10) NOT NULL,
CONSTRAINT PrimaryKeyProfessor PRIMARY KEY (professorCode)
)
;
CREATE TABLE Group
(sigle CHAR(7) NOT NULL,
noGroup INTEGER NOT NULL,
sessionCode INTEGER NOT NULL,
maxInscriptions INTEGER NOT NULL,
professorCode CHAR(5) NOT NULL,
CONSTRAINT PrimaryKeyGroup PRIMARY KEY
(sigle,noGroupe,sessionCode),
CONSTRAINT CESigleGroupeRefCours FOREIGN KEY (sigle) REFERENCES Cours,
CONSTRAINT CECodeSessionRefSession FOREIGN KEY (sessionCode) REFERENCES
Session,
CONSTRAINT CEcodeProfRefProfessor FOREIGN KEY(professorCode) REFERENCES
Professor
)
;
И вот мой текущий неработающий запрос:
SELECT DISTINCT Professor.firstName, Professor.lastName
FROM Professor, Group
WHERE Group.professorCode = Professor.professorCode
AND Group.sessionCode = 32003
AND (Group.sigle = 'INF1130' AND
Group.sigle = 'INF1110')
OR Group.sessionCode = 12004
AND (Group.sigle = 'INF3180' AND
Group.sigle = 'INF2110')
Я знаю, что есть способ объединить оба результата, но я не могу его найти.
В этом случае возможно только одно совпадение :
Результирующая таблица должна выглядеть так:
--------------------------
First Name Last Name
--------------------------
Denis Tremblay
Предлагаемое решение, данное Гордон Линофф, выглядит очень хорошо, за исключением того, что оно не возвращает мне таблицу, поскольку при следующем коде необходимо включить 4 курса и 2 кода сеанса. Проблема здесь в том, что необходимо проверить как условие, так и добавить результат. Допустим, условия для сеанса 12004 ни к чему не приводят, тогда я могу считать его NULL. Затем второе условие с сеансом 32003 дает мне одно совпадение. Он должен добавить оба результата, чтобы дать мне представленную таблицу.
Я хочу сделать один запрос только для этого.
Большое спасибо!
РЕДАКТИРОВАТЬ : переформулировано
РЕДАКТИРОВАТЬ2 : Приведен пример известного совпадения.
РЕДАКТИРОВАТЬ3 : дополнительное объяснение, почему предлагаемое решение не работает.
Пожалуйста, приведите примеры профессоров, которые соответствуют и не соответствуют условиям.
Только один профессор соответствует запросу. Он отвечает только для INF1110, INF1130 и 32003. Никто не соответствует INF3180, INF2110 и 12004. Он должен показать тот, который соответствует
Просто добавил пример! @GordonLinoff
Пример вывода бесполезен без сопоставления с образцом ввода, включая данные, которые должны появиться в наборе результатов нет. Вы сказали, что ваш запрос «не работает», но что это значит — вы получаете сообщение об ошибке? Слишком много результатов? Недостаточно? Включите текущий результат в свой вопрос вместе с примерными данными и объясните, почему он неверен.
@AlexPoole готово! Большое спасибо за понимание!
@GordonLinoff Я включил дополнительные пояснения непосредственно в сообщение под результирующей таблицей.
Итак... вам нужен профессор, который преподавал курсы обе в сессии либо, не обязательно все четыре? то есть (INF1130 и INF1110 в 32003) ИЛИ (INF3180 и INF2110 в 12004)? С ИЛИ, а не с И между этими двумя условиями? Вы всегда будете искать два значения sigle на sessionCode или это будет варьироваться?
@AlexPoole Я пытался изменить код, данный GordonLinoff, но безуспешно. Я попытался разделить (g.sessionCode, g.sigle) IN ( (32003, 'INF1130'), (32003, 'INF1110'), (12004, 'INF3180'), (12004, 'INF2110')) на ( g.sessionCode, g.sigle) IN ( (32003, 'INF1130'), (32003, 'INF1110')) ИЛИ (g.sessionCode, g.sigle) IN ( (12004, 'INF3180'), (12004, ' INF2110')). За исключением того, что это не сработало. И да, два символа за сессиюCode max


Подумайте: group by и having. Что еще более важно, думайте JOIN, JOIN, JOIN. Никогда используйте запятые в предложении from.
SELECT p.firstName, p.lastName
FROM Professor p JOIN
Group g
ON g.professorCode = p.professorCode
WHERE (g.sessionCode, g.sigle) IN ( (32003, 'INF1130'), (32003, 'INF1110'),
(12004, 'INF3180'), (12004, 'INF2110')
)
GROUP BY p.firstName, p.lastName
HAVING COUNT(DISTINCT g.sigl) = 4; -- has all four
Вот переведенный вопрос: Ищем коды и имена учителей, без повторения, которые преподавали сразу INF3180 и INF2110, во время сессии чей код 12004. Также код и имена учителей, которые преподавали курсы INF1130 или INF1110, во время сеанса код 32003
@GuillaumeLevesque. . . Четыре условия заключаются в том, что профессор преподавал все четыре класса. Это то, что делает этот запрос.
Извините, английский не мой основной язык. Таблица, которую я должен вернуть, это либо учителя, которые преподавали INF1130 и INF1110 в 32003 году, либо учителя, которые преподавали INF3180 и INF2110 в 12004 году. Плохо, я не могу правильно выразиться :/
использовать современное соединение
SELECT Professor.firstName, Professor.lastName
FROM Professor join "Group" g on
g.professorCode = Professor.professorCode
where g.sessionCode in( 32003,12004 )
AND g.sigle in( 'INF1130', 'INF1110','INF3180','INF2110')
group by Professor.firstName, Professor.lastName
having count( distinct sigle )=4
Кажется, вы хотите перечислить любого профессора, который либо преподавал INF1130 и INF1110 в 32003; или преподавали INF3180 и INF2110 в 12004 году. К сожалению, вы представили это как И (т. Е. Они должны преподавать все четыре курса - одну пару курсов И другой), а не ИЛИ (один набор курсов ИЛИ другой).
Как многословный способ расширить то, что я думаю, вы хотите:
SELECT p.firstName, p.lastName
FROM Professor p
WHERE (
EXISTS (
SELECT *
FROM GroupX g
WHERE professorCode = p.professorCode
AND sessionCode = 32003
AND sigle = 'INF1130'
)
AND EXISTS (
SELECT *
FROM GroupX g
WHERE professorCode = p.professorCode
AND sessionCode = 32003
AND sigle = 'INF1110'
)
)
OR (
EXISTS (
SELECT *
FROM GroupX g
WHERE professorCode = p.professorCode
AND sessionCode = 12004
AND sigle = 'INF3180'
)
AND EXISTS (
SELECT *
FROM GroupX g
WHERE professorCode = p.professorCode
AND sessionCode = 12004
AND sigle = 'INF2110'
)
);
Четыре подзапроса не будут очень эффективными. Вместо этого вы можете сделать несколько объединений.
Если вы всегда будете искать два значения sigle на sessionCode, вы можете изменить ответ Гордона, чтобы подсчитать количество совпадений для каждого sigle, добавив это в предложение group-by:
SELECT p.firstName, p.lastName
FROM GroupX g
JOIN Professor p
ON p.professorCode = g.professorCode
WHERE (g.sessionCode, g.sigle) IN ( (32003, 'INF1130'), (32003, 'INF1110'),
(12004, 'INF3180'), (12004, 'INF2110')
)
GROUP BY p.firstName, p.lastName, g.sessionCode
HAVING COUNT(*) = 2;
Если бы у вас был профессор, который преподавал все четыре, вы бы включили их в список дважды; если это может случиться, вы можете добавить свой DISTINCT обратно, хотя это кажется немного неправильным. Вы также можете использовать подзапрос и IN, чтобы избежать этого:
SELECT p.firstName, p.lastName
FROM Professor p
WHERE ProfessorCode IN (
SELECT professorCode
FROM GroupX
WHERE (sessionCode, sigle) IN ( (32003, 'INF1130'), (32003, 'INF1110'),
(12004, 'INF3180'), (12004, 'INF2110')
)
GROUP BY professorCode, sessionCode
HAVING COUNT(*) = 2
)
(Я изменил Group на GroupX, потому что это недействительный идентификатор, потому что это ключевое слово. Я предполагаю, что вы изменили свои настоящие имена — может быть, из другого языка?)
работал отлично. Я знаю знаю, что я сделал неправильно. Большое спасибо всем, кто мне помог!
Ага, с французского
Не уверен в Oracle или sql plus, но вы, вероятно, ищете, где или где существует. Поскольку одна запись не может удовлетворять обоим условиям.