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

Sql 如何编写检索特定电影系列的查询,sql,sql-server,Sql,Sql Server,我正在使用IMDB数据库,遇到以下问题: 获取特定电影的所有系列(包括前一部分): 如果你看一下下面的电影表,你可以看到一些记录有一个先前的部分。它引用了同一个表的movieId。 例如:我如何取回《指环王》中有前一部分的电影,以及前一部分等等 到目前为止,我得到的是: ;with SequenceChilds AS ( SELECT movie_id, previous_part, title FROM Movie WHERE movie_id = 194502 UNIO

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

获取特定电影的所有系列(包括前一部分):

如果你看一下下面的电影表,你可以看到一些记录有一个先前的部分。它引用了同一个表的movieId。

例如:我如何取回《指环王》中有前一部分的电影,以及前一部分等等

到目前为止,我得到的是:

;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
这给了我以下结果:

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


如果有人能给我指出正确的方向,我将不胜感激。提前谢谢

它不会返回所有记录,因为您正在筛选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;

希望这能有所帮助。

在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;

希望这有帮助。

这里的逻辑是首先为作为输入传递的任何电影ID查找父电影ID,然后使用递归查询从父级向下滚动以查找所有子级,下面的查询应该执行您想要的操作:

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

这里的逻辑是首先查找作为输入传递的任何电影ID的父电影ID,然后使用递归查询从父级向下滚动以查找所有子级,下面的查询应该执行您想要的操作:

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

在否决我的帖子之前,请给出一些反馈。我可以随时更新我的问题。使用您预期的输出更新问题,并发布您尝试使用的查询。最好定义一个系列,然后将电影的所有部分放到一个系列中。然后,您可以在每部电影中设置一个位置字段,以定义其在系列中的位置。与此链接相比,这对于查询来说是微不足道的structure@mkRabbani我刚刚用我到目前为止所得到的和预期的结果更新了这篇文章。我同意,“系列”应该被定义为数据中的一个数据项,它不应该被电影推断为续集的续集。假设你有一个包含9部电影的系列,如果你有第4部电影,你必须在“层次结构”上下循环,而不仅仅是通过某种ID或名称获取同一系列电影的细节。请在否决我的帖子之前给出一些反馈。我可以随时更新我的问题。使用您预期的输出更新问题,并发布您尝试使用的查询。最好定义一个系列,然后将电影的所有部分放到一个系列中。然后,您可以在每部电影中设置一个位置字段,以定义其在系列中的位置。与此链接相比,这对于查询来说是微不足道的structure@mkRabbani我刚刚用我到目前为止所得到的和预期的结果更新了这篇文章。我同意,“系列”应该被定义为数据中的一个数据项,它不应该被电影推断为续集的续集。假设你有一个包含9部电影的系列,如果你有第4部电影,你必须在“层次结构”上下循环,而不仅仅是通过某种ID或名称获取同一系列电影的细节。