Выберите записи только с одним значением SPECIFI C в столбце, где возможны несколько, с помощью операций набора - PullRequest
1 голос
/ 23 апреля 2020

Привет, я действительно борюсь с этим конкретным вопросом, когда практикую некоторые SQL запросы в составленном наборе данных.

Учитывая следующие таблицы:

  • Mov ie ( MovieID, Title, ProducerName)
  • DVD (MovieID, StoreID)
  • Store (StoreID, StoreName)

Я не уверен, как получить названия магазинов которые имеют только фильмы от производителя "BB C" (ProducerName = BB C). Я хочу попробовать использовать подзапросы и установить операции instread объединений.

У меня это в основном на догадках, поскольку я нигде не могу проверить запрос, но любая помощь будет очень признательна. Был бы лучший способ сделать это без использования соединения вообще?

select distinct(StoreName)
from STORE
where not exists (
(select distinct(Title)
from MOVIE JOIN DVDs
where DVD.StoreID == STORE.StoreID)
except
(select distinct(Title)
from MOVIE 
where producerName = ‘BBC’))

Ответы [ 2 ]

0 голосов
/ 23 апреля 2020

Если вы не хотите использовать какие-либо join s, вы можете сделать:

select s.*
from store s
where not exists (select 1
                  from (select dvd.*,
                               (select m.ProducerName
                                from movie m
                                where m.movieId = dvd.movieId
                               ) as ProducerName
                        from dvd
                       ) dvd
                  where dvd.ProducerName <> 'BBC' and
                        dvd.storeId = s.storeId
                 );

Вы также можете добавить предложение exists:

select s.*
from store s
where not exists (select 1
                  from dvd
                  where dvd.storeId = s.storeId and
                        exists (select 1
                                from movie m
                                where m.movieId = dvd.movieId and
                                      dvd.ProducerName <> 'BBC'
                               )
                 );

Однако Я считаю, что такие вложенные комбинации exists / not exists (или эквивалент с in / not in просто сбивают с толку - гораздо труднее понять, чем эквивалентные версии join.

0 голосов
/ 23 апреля 2020

Я бы использовал not exists следующим образом:

select s.*
from store s
where not exists (
    select 1 
    from dvd d
    inner join movie m on m.movieID = d.movieID
    where m.producerName <> 'BBC' and d.storeID = s.storeID
)

Это выбирает магазины, у которых нет mov ie от производителя, кроме BB C. Вы можете указать более точно c, добавив еще одно exists условие:

select s.*
from store s
where 
    exists (
        select 1 
        from dvd d
        inner join movie m on m.movieID = d.movieID
        where m.producerName = 'BBC' and d.storeID = s.storeID
    )
    and not exists (
        select 1 
        from dvd d
        inner join movie m on m.movieID = d.movieID
        where m.producerName <> 'BBC' and d.storeID = s.storeID
    )

Другим вариантом является агрегирование:

select s.storeID, s.storeName
from store s
inner join dvd d on d.storeID = s.storeID
inner join movie m on m.movieID = d.movieID
group by s.storeID, s.storeName
having bool_and(m.producerName = 'BBC')
...