我有一张电影桌,一部电影可以有一个previous_part。现在我想基于movie_id' 412331'使用星球大战电影获取图像中显示的所有电影。这可能是SQL(MsSQL / AzureSql)吗?
我很抱歉缺少信息,但我真的不知道如何开始用这个问题开始SQL查询。
更新
创建了一个递归查询,但它只有在我给予启动它的电影时才有效(请参阅代码块中的WHERE Prev.previous_part = 412332
)。所以在这个例子中,第五集将返回另外两部电影而第六集只会返回第七集。
With MovieList AS
(SELECT Prev.movie_id, Prev.title, Prev.description, Prev.previous_part, 1 as PrevLevel
FROM Movie as Prev
WHERE Prev.previous_part = 412332
UNION ALL
SELECT Mov.movie_id, Mov.title, Mov.description, Mov.previous_part, ML.PrevLevel + 1
FROM Movie as Mov
INNER JOIN MovieList AS ML
ON Mov.previous_part = ML.movie_id
WHERE Mov.previous_part IS NOT NULL)
SELECT * FROM MovieList
答案 0 :(得分:2)
这是您需要的递归CTE:
;with ml as (
--this is Anckor Query
select movie_id, title, previous_part
from movie where movie_id = 412325
union all
--this is Recursive Query
select m.movie_id, m.title, m.previous_part
from movie m
inner join ml on ml.previous_part = m.movie_id --link current prev to parent id
--if you want sequels instead of prev's change to m.previous_part = ml.movie_id
)
select * from ml
答案 1 :(得分:0)
@Igors comment是正确的递归查询,如果有多个级别的引用/层次结构,则可以使用递归公用表表达式。 Microsoft有一个很好的经理/员工示例。 https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx
这可能比你想要的更复杂但有点不清楚。
如果它只是一个参考级别意味着您不必匹配,那么一次又一次地匹配以找到您想要的所有内容,您可以使用自引用外部联接。
SELECT *
FROM
dbo.movies m1
LEFT JOIN dbo.movies m2
ON m1.movied_id = m2.previous_part
WHERE
m1.title LIKE '%Star Wars%'
OR m2.movied_ID IS NOT NULL
OR m2.title LIKE '%Star Wars%'
先生,我认为你很接近。没有你的数据集,它有点难以尝试,但这里是一个编辑,应该为您提供每个电影及其级别的完整列表。
;With MovieList AS (
SELECT Prev.movie_id, Prev.title, Prev.description, Prev.previous_part, 1 as PrevLevel
FROM Movie as Prev
WHERE Prev.previous_part IS NULL
UNION ALL
SELECT Mov.movie_id, Mov.title, Mov.description, Mov.previous_part, ML.PrevLevel + 1
FROM Movie as Mov
INNER JOIN MovieList AS ML
ON Mov.previous_part = ML.movie_id
)
SELECT * FROM MovieList
请注意,您可以在SELECT * FROM MovieList
上添加where语句,以便在生成层次结构后限制列表。
答案 2 :(得分:0)
这似乎解决了你的问题。
select *
into #t
from (
select 123 id,'xxx'nm,1234 pid
union all
select 1234, 'xl',12345
union all
select 12345,'xlxl',123456
) x
declare @mid int = 123
select x.* from #t x
where x.id = @mid
union all
select y.* from #t x
left join #t y
on x.pid = y.id
where x.id = @mid
union all
select z.* from #t x
left join #t y
on x.pid = y.id
left join #t z
on y.pid = z.id
left join #t xx
on z.pid = xx.id
where x.id = @mid
union all
select xx.* from #t x
left join #t y
on x.pid = y.id
left join #t z
on y.pid = z.id
left join #t xx
on z.pid = xx.id
where x.id = @mid
此查询最多可以播放4部电影,但您可以按照逻辑添加更多电影。 它也只有在您按最早的电影ID搜索时才有效。 如果你需要它来搜索两种方式,这应该工作
declare @mid int = 12345
select distinct * from
(
select x.* from #t x
where x.id = @mid
union all
select y.* from #t x
left join #t y
on x.pid = y.id or x.id = y.pid
where x.id = @mid
union all
select z.* from #t x
left join #t y
on x.pid = y.id or x.id = y.pid
left join #t z
on y.pid = z.id or y.id = z.pid
where x.id = @mid
union all
select xx.* from #t x
left join #t y
on x.pid = y.id or x.id = y.pid
left join #t z
on y.pid = z.id or y.id = z.pid
left join #t xx
on z.pid = xx.id or z.id = xx.pid
where x.id = @mid
) x