Как я могу написать запрос, который получает серию определенного фильма - PullRequest
0 голосов
/ 29 июня 2019

Я использую базу данных IMDB и застрял со следующей проблемой:

Получить все серии определенного фильма (с предыдущей частью):

Если вы посмотрите на таблицу фильмов ниже, то увидите, что в некоторых записях есть предыдущая_часть. Это ссылка на 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 ]

1 голос
/ 01 июля 2019

Логика здесь заключается в том, чтобы сначала найти идентификатор родительского фильма для любого идентификатора фильма, переданного в качестве ввода, а затем с помощью рекурсивного запроса выполнить откат от родительского уровня для поиска всех дочерних уровней. Следующий запрос должен делать то, что вы хотите:

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
0 голосов
/ 29 июня 2019

Он не возвращает вам все записи, так как вы фильтруете фильмы в первом разделе 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;

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...