【问题标题】:sql list actors who acted in a film before 1900 and also in a film after 2000sql 列出在 1900 年之前和 2000 年之后出演电影的演员
【发布时间】:2015-06-19 12:06:36
【问题描述】:

所以我有 3 个表,actor(id, name)、movie (id,name,year) 和 casts(aid, mid)(即 actor id 和 movie id)。我的目标是选择所有在 1900 年之前和 2000 年之后的电影中演出的演员。 我的查询是

select a.id 
from actor a, movie m1, casts c1, movie m2, casts c2
where a.id = c1.aid = c2.aid and c1.mid = m1.id and c2.mid = m2.id and
m1.year >2000 and m2.year <1900;

这个查询花了很长时间,似乎没有产生正确的结果。 那么有人可以帮帮我吗?

【问题讨论】:

  • 我的目标是选出所有在 1900 年之前和 2000 年之后出演电影的演员 有人活这么久吗?您可以通过不返回任何内容来优化查询。

标签: sql database sqlite select


【解决方案1】:

这也行

 

with first as (
SELECT Trim(mc.pid) as pid1
FROM   m_cast mc 
WHERE  Trim(mc.mid) IN (SELECT Trim(m.mid) 
                        FROM   movie m 
                        WHERE  Cast(Substr(Trim(m.year), -4) AS INTEGER) < 1970)
),
second as (
SELECT Trim(mc.pid) as pid2
FROM   m_cast mc 
WHERE  Trim(mc.mid) IN (SELECT Trim(m.mid) 
                        FROM   movie m 
                        WHERE  Cast(Substr(Trim(m.year), -4) AS INTEGER) > 1990) 
)
select first.pid1 from first intersect select second.pid2 from second

【讨论】:

    【解决方案2】:

    由于表的大小和大量的连接,此查询可能需要很长时间才能运行。

    此查询返回结果,因为数据库中有错误。

    正确的查询是:

    SELECT DISTINCT a1.fname, a2.lname 
    FROM 
    -- Create the table used to get all movies before 1900
    actor AS a1
    INNER JOIN casts AS c1
    ON a1.id=c1.pid
    INNER JOIN movie as m1
    on m1.id = c1.mid,
    -- Create the table used to get all movies after 2000
    actor as a2
    INNER JOIN casts AS c2
    ON a2.id=c2.pid
    INNER JOIN movie as m2
    on m2.id = c2.mid
    -- Only display actors that have played before 1900 and after 2000
    WHERE m1.year < 1900 AND m2.year > 2000 AND a1.id = a2.id;
    

    【讨论】:

    • 欢迎来到 StackOverflow。以下网址向您展示了如何格式化您的答案以使其更易于阅读。 stackoverflow.com/help/formatting。阅读后,您可以编辑您的答案,以使代码清晰可见。顺便说一句,不是我对你的回答投了反对票。
    • 我相信你需要加入a1和a2。
    【解决方案3】:

    我认为问题在于表达式a.id = c1.aid = c2.aid。如果我没记错的话,这首先将c1.aidc2.aid 进行比较,然后将布尔结果与a.id 进行比较。

    你可以试试这个:

    select a.id 
    from actor a
    inner join casts c1 on c1.aid = a.id
    inner join casts c2 on c2.aid = a.id
    inner join movie m1 on c1.mid = m1.id
    inner join movie m2 on c2.mid = m2.id 
    where m1.year >2000 and m2.year <1900; 
    

    或者,如果您更喜欢内部连接的 where 语法,只需将 a.id = c1.aid = c2.aid 更改为 a.id = c1.aid and a.id = c2.aid

    【讨论】:

      【解决方案4】:

      要获取在两个日期范围内参演电影的演员,请使用两个子查询。像这样的:

      select yourFields
      from yourTables
      where actorId in (subquery to get actor id's for one date range)
      and actorId in (subquery to get actor id's for second  date range)
      

      你可以算出细节。

      【讨论】:

      • 我们可以在没有子查询的情况下做到这一点吗?因为我们还没有那么远,所以我想可能还有另一种方法
      • @Big_tboy 子查询通常比连接更容易理解和维护。使用连接的一个常见原因是优化速度,但这在 SQLite 中通常不是有用的优化。
      猜你喜欢
      • 1970-01-01
      • 2020-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多