【问题标题】:Can't solve this SQL query involving subqueries for given film database无法解决这个涉及给定电影数据库子查询的 SQL 查询
【发布时间】:2020-11-11 20:01:21
【问题描述】:

Relational Schema

鉴于上面的关系模式,我似乎无法弄清楚如何解决这个查询:

  1. 编写 SQL 查询以查找所有商店携带的电影片名(即,在所有商店的 库存)。假设可以有任意数量的商店(即,您不能假设 一定数量的商店)。您的查询也不能使用 COUNT()。 (提示:不是 使用子查询很难找到没有特定电影的商店。)

【问题讨论】:

    标签: sql database subquery schema


    【解决方案1】:

    让我们定义一个您提供的架构的简化版本,其中只包含我们需要的表和列,以及一些可以使用的代表性数据。

    (为了以后参考,您可以通过为我们做这一步来“帮助我们帮助您”。这也表明您已经对问题涉及到了一些思考)

    DECLARE @t_film TABLE
    (   film_id INT)
    
    DECLARE @t_store TABLE
    (   store_id INT)
    
    DECLARE @t_inventory TABLE
    (   inv_id INT IDENTITY,
        store_id INT,
        film_id INT
    )
    
     INSERT INTO @t_film
     VALUES (1),
            (2),
            (3),
            (4),
            (5),
            (6)
    
     INSERT INTO @t_store
     VALUES (1),
            (2),
            (3),
            (4)
    
     INSERT INTO @t_inventory
     VALUES (1,1),
            (1,3),
            (1,4),
            (1,5),
            (2,1),
            (2,4),
            (2,5),
            (3,1),
            (3,2),
            (3,3),
            (3,5),
            (4,1),
            (4,2),
            (4,3),
            (4,4),
            (1,6),
            (2,6),
            (3,6),
            (4,6)
    -- Every store has films 1 & 6
    

    现在让我们从他们给你的提示开始,然后从那里得到它。 “使用子查询查找没有特定电影的商店。”

    -- First create a list of every store as if it had every film
    SELECT *
      FROM @t_film f
     CROSS JOIN @t_store s
    --Then compare that to the actual inventory of each store
      LEFT JOIN @t_inventory i ON f.film_id = i.film_id
                              AND s.store_id = i.store_id
    --Then filter that list to only the films which dont appear in a particular store.
     WHERE i.inv_id IS NULL
    

    然后我们可以选择所有未出现在该列表中的电影。我们把上面的查询变成一个子查询,并用它来过滤我们的结果。

    SELECT *
      FROM @t_film r
     WHERE film_id NOT IN (SELECT f.film_id
                             FROM @t_film f
                            CROSS JOIN @t_store s
                             LEFT JOIN @t_inventory i ON f.film_id = i.film_id
                                                     AND s.store_id = i.store_id
                            WHERE i.inv_id IS NULL)
    

    可能有一种更优雅的方法可以做到这一点,但我认为这种方法最容易遵循逻辑。例如,不使用 NOT IN,您可以使用另一个带有 NULL 检查的 LEFT JOIN 来实现相同的目的。

    SELECT r.*
      FROM @t_film r -- result
      LEFT JOIN (SELECT f.film_id
                   FROM @t_film f
                  CROSS JOIN @t_store s
                   LEFT JOIN @t_inventory i ON f.film_id = i.film_id
                                           AND s.store_id = i.store_id
                  WHERE i.inv_id IS NULL) inv ON r.film_id = inv.film_id
     WHERE inv.film_id IS NULL
    

    关键是要理解逻辑。从那里您可以找到任意数量的解决方案。

    【讨论】:

    • 我很抱歉没有进一步简化它,我是这个网站的新手。非常感谢您为我解决了这个问题,效果很好!
    猜你喜欢
    • 1970-01-01
    • 2016-07-26
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    相关资源
    最近更新 更多