Как определить, существует ли значение в соединительной таблице и вернуть ноль или единицу? - PullRequest
2 голосов
/ 25 февраля 2012

Я использую SQL Server 2008 R2

Я пытаюсь написать один запрос, который вернет только то, что мне нужно. Я добавлю MovieID и верну список ВСЕХ жанров. Если фильм представляет определенный жанр (имеет связанную запись в таблице соединений), проверенное значение будет равно 1. Если нет, то 0.

Мой набор результатов должен выглядеть следующим образом:

GenreID    Genre    Checked
1          ABC      0
2          DEF      1
3          HIJ      0
4          KLM      1

Моя первая таблица называется Жанры. Это выглядит так:

GenreID    Genre
1          ABC
2          DEF
3          HIJ
4          KLM

Моя вторая таблица называется Фильмы. Это выглядит так:

MovieID   Title
1         Blah
2         Foo
3         Carpe
4         Diem

Моя третья таблица - это таблица соединений с именем Movies_Genres. Это выглядит так:

MovieID   GenreID
1         2
1         1
1         4
2         1
2         3
3         4
4         1

Обычно я бы сделал пару запросов и несколько циклов, чтобы справиться с этим, но я действительно хочу, чтобы база данных выполняла работу здесь. Как настроить мой запрос, чтобы получить нужный набор результатов всего одним запросом?

Вот начальный запрос:

SELECT  GenreID, 
        Genre
FROM    Genres

Заранее спасибо за помощь !!!

Ответы [ 3 ]

3 голосов
/ 25 февраля 2012
SELECT g.GenreID, g.Genre, Checked = CASE WHEN EXISTS
      (SELECT 1 FROM dbo.Movies_Genres AS mg
         INNER JOIN dbo.Movies AS m
         ON mg.MovieID = m.MovieID
         WHERE mg.GenreID = g.GenreID
         AND m.MovieID = @MovieID) THEN 1 ELSE 0 END
FROM dbo.Genres AS g
ORDER BY g.GenreID;

Если для dbo.Movies_Genres(MovieID, GenreID) существует уникальное ограничение или первичный ключ, то это может быть просто:

SELECT g.GenreID, g.Genre, Checked = COUNT(mg.GenreID)
    FROM dbo.Genres AS g
    LEFT OUTER JOIN dbo.Movies_Genres AS mg
    ON g.GenreID = mg.GenreID
    AND mg.MovieID = @MovieID
    GROUP BY g.GenreID, g.Genre;

... так как счет для любого жанра может быть только 0 или 1 с учетом одного @MovieID.

2 голосов
/ 25 февраля 2012

Довольно просто, используя CASE;

SELECT DISTINCT g.GenreID, g.Genre, 
  CASE WHEN mg.MovieID IS NULL THEN 0 ELSE 1 END Checked
FROM Genres g 
LEFT JOIN Movies_Genres mg
  ON g.GenreID=mg.GenreID 
    AND mg.MovieId=@MovieID;

Демо здесь .

Редактировать: Если записи гарантированно будут уникальными в Movies_Genres, вы можете отказатьсяОТЛИЧИЕ.

1 голос
/ 25 февраля 2012

@MovieID - это фильм, по которому вы хотите отфильтровать.

SELECT  Genres.GenreID, 
        Genres.Genre,
        CASE WHEN (Movies_Genres.GenreID IS NULL)
            THEN 0
            ELSE 1 
        END AS Checked
FROM    Genres LEFT JOIN
        Movies_Genres ON Movies_Genres.GenreID = Genres.GenreID AND
                        MovieID = @MovieID 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...