检索列SQL数据库中的重复值

时间:2018-03-25 10:16:58

标签: sql duplicates

我有一个小型数据库,其中包含一个表格,用于保存电影中每一行的信息(例如,电影名称,电影运行时间,电影评级),我还有一个单独的类型表,其中包含一系列类型(恐怖,行动等)。

我有一个将电影链接到一个类型的关联表(一个典型的行将包含该行的唯一ID,genreId和movieId)。

我写了一个查询,它回退了用户观看的所有类型;但是,它正在删除重复的行值,并且正在给我一些看似独特的计数。

以下是SQL语句:

SELECT g.Type,
       g.Id
FROM GenreTable g
WHERE
  g.Id in (
    SELECT gma.GenreId
    FROM MovieGenreAssociationTable gma
    WHERE gma.MovieId in (
        SELECT uma.MovieSeriesId
        FROM UserMovieAssociationTable uma
        WHERE uma.UserId = '1'
      )
  );

返回用户观看过的所有类型,但我注意到它没有带回我知道存在于关联表中的重复项。

我如何获得这些副本?

1 个答案:

答案 0 :(得分:0)

您没有在单个表格上JOIN而是SELECT,因此除非GenreTable中存在重复项,否则它永远不会返回任何重复项。

如果您执行SELECT a FROM tbl WHERE b IN (1,1,1,1,1)之类的操作,它将只返回一行 - 而不是五行。即使你有一个复杂的WHERE,它仍然是一个简单的IN条款。

更新:JOIN上的快速和脏的复习。

我实际上建议您寻找SQL教程。 我对此笔记的完整性没有任何说法 - 相反,First google hitsecond hit

假设你有两个简单的表:

  a.id  a.a              b.id  b.b
  1     1                1     'Hello'
  2     1                2     'World'
  3     2                7     'foobar'
  4     3                

如果您在a和b ON(a.a = b.id)之间运行JOIN,则查询将选择a中的所有记录;然后每个将加入中所有匹配记录。这就是JOIN的用途。

在这种情况下,第二列和第三列将始终相等:

  1     1    1   'Hello'
  2     1    1   'Hello'
  3     2    2   'World'

请注意,a的第四行被丢弃,因为它与 no 匹配,并且b的第三行从未被选中。 b的第二行被选中两次,因为有两个具有匹配的元素。

LEFT JOIN的工作原理相同,只是如果查询左侧有无匹配(即表a),就像第四行一样,那一行选择完全相同;但是来自b的额外字段将被NULL替换。你得到的另一行JOIN子句ON(a.a = b.id)实际上是假的:

    4   3   NULL   NULL

(你可以用它来选择b中没有匹配的行:只需指定例如WHERE b.primary_key_of_b IS NULL)。

您的案例

您应该执行以下操作:

SELECT
  g.Type,
  g.Id
FROM GenreTable AS g
  JOIN MovieGenreAssociationTable AS gma ON (gma.GenreId = g.Id)
  JOIN UserMovieAssociationTable AS uma ON (uma.MovieSeriesId = gma.MovieId)
WHERE uma.UserId = 1;

然后,您可以GROUP BY,例如输入和ID以获取针对每种类型观看的COUNT()电影。

但是...

假设你有一个GenreTable有两行(Id = 123,Type =" Science Fiction" Id = 456,Type =" Comedy"),一个有一个的电影表行(777," Galactic Quest"),MovieGenreAssociationTable(123,777)和(456,777),因为那部电影也是一部伟大的喜剧,最后用户1只观看了电影777.你会得到:

Genre                       gma         uma        Movie
123  "Science Fiction"      123, 777    777, 1     777, "Galaxy Quest"
456  "Comedy"               456, 777    777, 1     777, "Galaxy Quest"

并且会看到用户1看过两部电影 - 一部SciFi,一部喜剧。

在这种情况下,您需要接受结果(他观看了多少喜剧?一个。多少个SciFis?一个),或者做一个更复杂的查询,你必须决定哪个是主要类型< / em>的。否则你会得到不合逻辑的结果(&#34;有多少喜剧?一。多少部电影?一部。那么非喜剧的数量是一减一,即零?不,它再一次 - 等等,什么?& #34;。)

在这种情况下,您可以在MovieGenreAssociation中添加一列用于此目的,一个布尔列&#34; IsMainGenre&#34;。因此,当你想知道观看了多少喜剧时,你会像上面那样做。但是当你按流派分割电影时,你可以添加AND IsMainGenre=1并计算&#34; Galaxy Quest&#34;在SciFis中,但不是喜剧或模仿之中。