【发布时间】:2020-11-11 20:01:21
【问题描述】:
鉴于上面的关系模式,我似乎无法弄清楚如何解决这个查询:
- 编写 SQL 查询以查找所有商店携带的电影片名(即,在所有商店的 库存)。假设可以有任意数量的商店(即,您不能假设 一定数量的商店)。您的查询也不能使用 COUNT()。 (提示:不是 使用子查询很难找到没有特定电影的商店。)
【问题讨论】:
标签: sql database subquery schema
鉴于上面的关系模式,我似乎无法弄清楚如何解决这个查询:
【问题讨论】:
标签: sql database subquery schema
让我们定义一个您提供的架构的简化版本,其中只包含我们需要的表和列,以及一些可以使用的代表性数据。
(为了以后参考,您可以通过为我们做这一步来“帮助我们帮助您”。这也表明您已经对问题涉及到了一些思考)
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
关键是要理解逻辑。从那里您可以找到任意数量的解决方案。
【讨论】: