无法解决此 SQL 查询涉及给定电影数据库的子查询
Can't solve this SQL query involving subqueries for given film database
Relational Schema
鉴于上面的关系模式,我似乎无法弄清楚如何解决这个查询:
- 写一个 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
重点是理解逻辑。从那里您可以找到任意数量的解决方案。
Relational Schema
鉴于上面的关系模式,我似乎无法弄清楚如何解决这个查询:
- 写一个 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
重点是理解逻辑。从那里您可以找到任意数量的解决方案。