2015-09-15 3 views
0

У меня есть 3 стола Доктор, пациент и посещение.Основная помощь по SQL-запросам (не существует)

Стол врача имеет доктор, имя и город.

Стол пациента имеет идентификатор пациента, имя и город.

Посетите таблицу DoctorID, PatientID, NumVisits.

Я пытаюсь найти всех врачей, которые не были посещены пациентом определенного города (скажем, Нью-Йорк).

Я очень новичок в написании запросов, и я не могу заставить его работать.

Мой КОД:

SELECT DoctorId, 
    Doctor.Name 
FROM Visit 
JOIN Doctor using(DoctorID) 
JOIN Patient using(PatientID) 
WHERE NOT EXISTS 
    (SELECT DoctorId, 
      Doctor.Name 
    FROM Visit 
    JOIN Doctor using(DoctorID) 
    JOIN Patient using(PatientID) 
    WHERE Patient.City = 'New York'); 

Может кто-то пожалуйста, объясните мне, что я делаю не так? Может быть, весь мой подход неверен.

+0

Вы, безусловно, не нужно 6 запросов для достижения этой цели! Это поможет сделать шаг назад и подумать об этом с другой точки зрения. Хорошее эмпирическое правило заключается в том, что вы никогда не должны выполнять больше объединений, чем в вашем запросе есть таблицы! – DanHabib

ответ

0

вы можете сделать это следующим образом:

SELECT DoctorId, Doctor.Name 
From Doctor 
Where DoctorId NOT IN (Select DoctorId From Visit 
         Where PatientID IN (Select PatientID From Patient 
               Where City = 'New York')) 

Таким образом, вы выбрать пациент из указанного города в самом внутреннем отборе, то вы берете DoctorId где посещаются теми пациентами, и, наконец, выбрать врачами, которые не являешься среди них.

+0

Это будет работать, но это может смутить оптимизатор запросов большинства СУБД ... – Brad

1

Вы должны подключить свой подзапрос с основным запросом. Прямо сейчас в вашем подзапросе вы выбираете всех врачей из Нью-Йорка, и, конечно, у вас есть хотя бы один. Вот почему WHERE NOT EXISTS (1 or more rows) никогда не будет правдой. Попробуйте что-то вроде этого

SELECT DoctorId, 
    Doctor.Name 
FROM Visit 
JOIN Doctor using(DoctorID) 
JOIN Patient using(PatientID) 
WHERE NOT EXISTS 
    (SELECT * 
    FROM Visit 
    JOIN Patient using(PatientID) 
    WHERE Patient.City = 'New York') 
    and Visit.Doctorid=Doctor.DoctorID -- Doctor.DoctorID from main query 
; 

И (спасибо @ Брэд): Поскольку пациент не используется во внешнем запросе, вы можете удалить первый РЕГИСТРИРУЙТЕСЬ против пациента и посещения. Фактически, вы ДОЛЖНЫ удалить соединение с пациентом и посещением во внешнем запросе, или вы будете пропускать записи для врачей, у которых нет пациентов. Результат будет

SELECT DoctorId, 
    Doctor.Name 
FROM Doctor 
WHERE NOT EXISTS 
    (SELECT * 
    FROM Visit 
    JOIN Patient using(PatientID) 
    WHERE Patient.City = 'New York') 
    and Visit.Doctorid=Doctor.DoctorID -- Doctor.DoctorID from main query 
; 
+1

Так как Patient не используется во внешнем запросе, вы можете удалить первый 'JOIN' против' Patient' и 'Visit'. Фактически, вы ДОЛЖНЫ удалить соединение с пациентом и посещением во внешнем запросе, или вы будете пропускать записи для врачей, у которых нет пациентов. – Brad

+1

Спасибо @Brad! Не думал об этом –