我的问题是按照导演的电影数量降序列出所有导演10部或以上电影的导演。返回导演的姓名和导演的电影数量
我有两个表,一个是Director表,它具有ID(主键),MID,PID列。另一个是具有PID(主键),名称,性别列的人员表。
以下是我的查询
SELECT Name, COUNT(*) movies_directed
FROM Director
LEFT JOIN Person USING(PID)
GROUP BY PID
HAVING movies_directed >= 10
ORDER BY movies_directed DESC;
但是这里的问题是,在Person中有多个具有相同PID的行。
这是示例数据
当我执行查询时
SELECT * FROM Person WHERE Name LIKE '%Andy Serkis%';
结果是
index PID Name Gender
4 'nm0785227' **' Andy Serkis'** 'Male'
36821 'nm0785227' 'Andy Serkis' 'Male'
第一行中的名称有一个额外的空间。这些重复项需要删除
答案 0 :(得分:0)
但是这里的问题是在Person中有多个具有相同PID的行。
这真的没有道理。大概PID
是Person
表的主键。这意味着Person
中每个值只有一行。 Director
中可能有多行-因为一个人可以导演多部电影。
我认为您的查询将返回正确的结果。但是,它的措词不正确。
使用内部联接会更好,因为您只考虑导演了至少一部电影的人(实际上,至少有十部电影)。所以:
SELECT p.Name, COUNT(*) as movies_directed
FROM Person p JOIN
Director d
USING (PID)
GROUP BY PID, p.Name
HAVING movies_directed >= 10
ORDER BY movies_directed DESC;
注意:
USING
子句中的列。COUNT(*)
。对于LEFT JOIN
,这通常是不合适的。通常,您需要在 second 表中计算匹配项。答案 1 :(得分:0)
这应该可以解决问题。
SELECT Name, COUNT(*) movies_directed
FROM Director
Where exists
(SELECT 1 FROM Person
WHERE Director.PID = Person.PID)
GROUP BY PID
HAVING movies_directed >= 10
ORDER BY movies_directed DESC;
但是理想情况下,您想要引用具有唯一人员ID的单独表并使用join子句。
答案 2 :(得分:0)
首先执行以下DELETE
语句:
delete from Person
where exists (
select 1 from Person p
where p.pid = Person.pid and p.name <> Person.name and p.rowid < Person.rowid
);
此操作将删除重复的PID
,仅保留较低RowId
的那个。
然后执行以下UPDATE
语句:
update Person
set name = trim(name);
修复任何在结尾或开头包含空格的名称。
如果还有其他不一致之处,您也可以执行类似的UPDATE
语句。
然后,如果您对表使用适当的别名并用它们限定列,那么您的代码应该可以工作。