如何编写查询来检索特定电影的系列

时间:2019-06-29 09:48:29

标签: sql sql-server

我正在使用IMDB数据库,但遇到以下问题:

获取特定电影的所有系列(及其上一部分):

如果您查看下面的电影表,您会发现某些记录具有previous_part。它引用同一表的movieId。 enter image description here

例如:我如何获取具有上一部分的指环电影的领主,以及如何获取上一个部分等。

我到目前为止所拥有的是:

;with SequenceChilds AS 
(
  SELECT movie_id, previous_part, title
  FROM Movie
  WHERE movie_id = 194502

  UNION ALL

  SELECT m.movie_id, m.previous_part, m.title
  FROM Movie m
  inner JOIN SequenceChilds p ON p.previous_part = m.movie_id
) 
select * from SequenceChilds

这给了我以下结果:

enter image description here

似乎迭代不够深入,因为我从结果中期望得到的结果是:

enter image description here

很高兴有人能指出我正确的方向。预先感谢!

2 个答案:

答案 0 :(得分:1)

这里的逻辑是首先找到作为输入传递的任何电影ID的父电影ID,然后使用递归查询从父级别向下滚动以找到所有子级别,以下查询应做您想做的事情:< / p>

CREATE TABLE #movie ([Movie_ID] INT, [Previous_Part] INT, [Title] VARCHAR(25))

INSERT INTO #movie ([Movie_ID], [Previous_Part], [Title])
VALUES
    (194500, NULL, 'Part 1'),
    (194501, 194500, 'Part 2'),
    (194502, 194501, 'Part 3'),
    (194503, 194502, 'Part 4'),
    (194504, 194503, 'Part 5')

/*** QUERY Starts Here ***/

DECLARE @SerchID INT 
SET @SerchID  = 194503 -- Movie to search

;WITH Parent AS
(
    SELECT *, 1 AS Lvl FROM #movie 
    WHERE [Movie_ID] = @SerchID

    UNION ALL

    SELECT mv.*, Lvl+1 AS Lvl FROM #movie mv
    INNER JOIN Parent p ON mv.[Movie_ID] = p.[Previous_Part] 
)
,RCTE AS 
(
    SELECT mv.* FROM #movie mv
    WHERE [Movie_ID] = (SELECT TOP 1 [Movie_ID] FROM Parent ORDER BY Lvl DESC)

    UNION ALL

    SELECT mv.* FROM #movie mv
    INNER JOIN RCTE rc ON rc.[Movie_ID] = mv.[Previous_Part] 
)

SELECT * FROM RCTE r

结果如下,

Movie_ID    Previous_Part   Title
194500      NULL            Part 1
194501      194500          Part 2
194502      194501          Part 3
194503      194502          Part 4
194504      194503          Part 5

答案 1 :(得分:0)

在过滤CTE第一节中的电影时,它不会返回所有记录。此查询可以为您提供所有电影及其续集,

;With MoviesWithSequels AS
(
SELECT m.movie_id, m.previous_part, m.title
FROM Movie m WHERE m.previous_part is not null
)
SELECT * FROM MoviesWithSequels

UNION

SELECT p.movie_id, p.previous_part, p.title FROM Movie p 
INNER JOIN MoviesWithSequels MS ON p.movie_id = MS.previous_part;

然后您可以根据CTE中的标题进行过滤,如下所示,

;With MoviesWithSequels AS
(
SELECT m.movie_id, m.previous_part, m.title
FROM Movie m WHERE m.previous_part is not null AND m.Title Like 'Lord of the Rings%'
)
SELECT * FROM MoviesWithSequels

UNION

SELECT p.movie_id, p.previous_part, p.title FROM Movie p 
INNER JOIN MoviesWithSequels MS ON p.movie_id = MS.previous_part;

希望这会有所帮助。