我有一个小型数据库,其中包含一个表格,用于保存电影中每一行的信息(例如,电影名称,电影运行时间,电影评级),我还有一个单独的类型表,其中包含一系列类型(恐怖,行动等)。
我有一个将电影链接到一个类型的关联表(一个典型的行将包含该行的唯一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'
)
);
返回用户观看过的所有类型,但我注意到它没有带回我知道存在于关联表中的重复项。
我如何获得这些副本?
答案 0 :(得分:0)
您没有在单个表格上JOIN
而是SELECT
,因此除非GenreTable
中存在重复项,否则它永远不会返回任何重复项。
如果您执行SELECT a FROM tbl WHERE b IN (1,1,1,1,1)
之类的操作,它将只返回一行 - 而不是五行。即使你有一个复杂的WHERE
,它仍然是一个简单的IN
条款。
我实际上建议您寻找SQL教程。 我对此笔记的完整性没有任何说法 - 相反,。 First google hit,second 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中,但不是喜剧或模仿之中。