如何确定联结表中是否存在值并返回零或一?

时间:2012-02-25 18:02:11

标签: tsql sql-server-2008-r2

我正在使用SQL Server 2008 R2

我正在尝试编写一个只返回我需要的查询。我将放入一个MovieID并获取所有类型的列表。如果影片代表特定类型(在联结表中有相关​​记录),则Checked值将为1.如果不是,则为0.

我的结果集应如下所示:

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

My First表名为Genres。它看起来像这样:

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 个答案:

答案 0 :(得分:3)

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;

...因为任何类型的计数在给定@MovieID的情况下只能是0或1。

答案 1 :(得分:2)

使用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;

演示here

编辑:如果在Movies_Genres中保证条目是唯一的,您可以选择删除DISTINCT。

答案 2 :(得分:1)

@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