您不是在单个表上创建 JOIN 而是 SELECT,因此它永远不会返回任何重复项,除非它们存在于 GenreTable 中。
如果您执行SELECT a FROM tbl WHERE b IN (1,1,1,1,1) 之类的操作,它将只返回一行,而不是五行。即使你有一个复杂的WHERE,它仍然是一个简单的IN 子句。
更新:关于 JOIN 的快速而肮脏的复习。
我实际上建议您查找 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之间运行JOIN,ON(a.a = b.id),查询将选择a中的所有记录; 他们中的每一个将被加入到b中的所有匹配记录。这就是 JOIN 的用途。
在这种情况下,第二列和第三列总是相等的:
1 1 1 'Hello'
2 1 1 'Hello'
3 2 2 'World'
请注意,a 的第四行被丢弃,因为它有 no 个匹配项,而 b 的第三行根本没有被选中。 b 的第二行被选中两次,因为 a 有两个元素匹配。
A LEFT JOIN 的工作方式相同,除了如果查询左侧(即表 a)没有匹配,就像第四行发生的那样,则选择该行都一样;但是来自 b 的额外字段被 NULL 替换。您会得到另一行,其中JOIN 子句ON(a.a = b.id) 实际上是错误的:
4 3 NULL NULL
(您可以使用它来选择在 b 中没有匹配项的 a 行:只需指定例如 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"),一个包含一行的 Movie 表(777,“Galactic Quest”),包含 (123, 777) 和 (456, 777) 的 MovieGenreAssociationTable,因为那部电影也是一部很棒的喜剧,最后用户 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 看过两部电影 - 一部科幻片,一部喜剧片。
在这种情况下,您需要要么接受结果(他看了多少部喜剧?一部。一部科幻片?一部),或者进行更复杂的查询您必须确定哪个是主要类型。否则你会得到不合逻辑的结果(“有多少喜剧?一部。多少部电影?一部。那么非喜剧的数量是一减一,即零?不,又是一 - 等等,什么?”)。
在这种情况下,您可以为此目的在 MovieGenreAssociation 中添加一个列,即布尔列“IsMainGenre”。因此,当您想知道一个人看了多少部喜剧时,您可以按照上面的方法进行。但是,当您按类型划分电影时,添加 AND IsMainGenre=1 并计算“银河探秘”在科幻片中,而不是在喜剧或模仿中。