2015-11-11 3 views
0

Вопрос: Напишите инструкцию SQL для извлечения имени и фамилии гостей, у которых никогда не было зарезервировано помещение для семьи ('F'). Вы должны использовать подзапрос. (Результат = 4 строки)Sub Query SQL - выберите

Мой код:

select firstname,lastname 
from guest, reservation 
where reservation.guestid=guest.guestid 
and roomnum in 
(select roomnum 
from room 
where roomtype = 'f'); 

Я получаю 26 строк. Я думаю, что я делаю запрос sub неправильно.

+0

Не могли бы вы привести пример вашего набора данных? – Undo

+0

Вы уже закрыли функцию EXISTS() еще в своем классе? –

+0

Нет, у нас нет, только подзапросы и соединения до сих пор. Спасибо за помощь, которую мне помогли, я переделаю ее с тем, как нас учат в моем классе, но я видел свою ошибку и понимал, как вы это сделали! Спасибо! – iz2015

ответ

0

Вы должны избегать РЕГИСТРИРУЙТЕСЬ целиком, а просто использовать подзапрос:

SELECT firstname, lastname 
FROM guest 
WHERE guestid NOT IN (
    SELECT guestid 
    FROM reservation, room 
    WHERE reservation.roomnum=room.roomnum 
    AND roomtype='f' 
) 

Это позволяет избежать получать тот же гость несколько раз, если у них есть несколько оговорок.

+0

Спасибо! Это именно то, что нас спрашивают! – iz2015

0

Er, Кто вас учит? Объединенные с запятыми соединения, где они заменены явными объединениями более двадцати лет назад и больше не должны использоваться. (Используйте вместо этого from guest join reservation on reservation.guestid = guest.guestid.)

Что касается вашей проблемы: вы хотите выбрать имена от гость. Нет здесь. Тогда вы хотите убедиться, что нет F бронирования существует для гостя. Предложение NOT EXISTS или обычно немного проще: предложение NOT IN.

select firstname, lastname 
from guest 
where guestid not in 
(
    select guestid 
    from reservation 
    where roomnum in 
    (
    select roomnum 
    from room 
    where roomtype = 'F' 
) 
); 
+0

Вам не нужен второй подзапрос? Присоединение к бронированию и номер получает тот же результат. –

+0

@Tab Alleman: Да, это правда; вам не нужен подзапрос, вы можете использовать соединение. Но я могу также утверждать: вам не нужно соединение, вы можете использовать подзапрос. Один не лучше другого. Мне больше нравится подзапрос. Я говорю: «Найдите оговорки, где комната - комната F». Вы говорите: «Узнайте для каждой бронировки, какой тип номера она есть, а затем сохраните тип комнаты F». Оба подхода верны. Я нахожу мой более интуитивным и прямым. Но это может быть вопросом личного предпочтения в конце. –

+0

Очень полезно! Спасибо! Я переделаю его так, как мой класс требует, чтобы это было сделано, но ваша помощь определенно решила его. BTW. Хотя второй подзапрос был тем, что я считал правильным, он должен быть присоединением к этой части. – iz2015

0

Вам нужен список гостей, которые никогда не делали оговорку семейного типа (первый суб-запрос заботится о нем), а также вы должны удалить гостей, которые никогда не делали оговорку тоже (второй суб-запрос будет обрабатывать его).

SELECT firstname, lastname 
FROM guest 
WHERE guestid NOT IN (
    SELECT guestid 
    FROM reservation, room 
    WHERE reservation.roomnum=room.roomnum 
    AND roomtype='f' 
) and guestid in 
(
    SELECT guestid 
    FROM reservation, room 
    WHERE reservation.roomnum=room.roomnum 
) 

Ознакомьтесь с созданным для скрипта SQL скриптом. http://sqlfiddle.com/#!9/b4221/2/0

+0

Спасибо за ссылку, безусловно, использовать ее для будущих целей! Мне пришлось немного подкорректировать код, чтобы он соответствовал требованиям задания, но в остальном это было очень полезно, спасибо! – iz2015

+0

Не было необходимости, чтобы гости находили по крайней мере одну оговорку, поэтому второй подзапрос не нужен. Даже если бы это было так, в нем нет фида для подключения к столовой, так как вся информация присутствует в резервировании стола. И тогда вам не следует поощрять синтаксис соединения, устаревший уже более двадцати лет (с SQL-92). –