无法解决此 SQL 查询涉及给定电影数据库的子查询

Can't solve this SQL query involving subqueries for given film database

Relational Schema

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

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

让我们定义一个简化版本的模式,您只提供我们需要的表和列,以及一些有代表性的数据。

(为了以后的参考,您可以帮我们做这一步,“帮助我们帮助您”,也说明您已经考虑到了问题所在)

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 所有没有出现在该列表中的电影。我们把上面的查询变成一个子查询,并用它来过滤我们的结果。

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

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