在SQL中使用内部联接的递归CTE

时间:2019-12-18 14:57:47

标签: sql recursion join db2 recursive-cte

我必须进行递归CTE才能将所有认识kevin bacon的演员都还给我,以便更好地了解我的数据库。我有Movies表和Actors和Movies2Actors表,其中仅包含actorid和movieid,我需要只让两个演员认识熏肉的人 例如,您可能想知道如何将Alfred Hitchcock连接到Kevin Bacon。一个答案是: 阿尔弗雷德·希区柯克(Alfred Hitchcock)和奥森·威尔斯(Orson Welles)一起参加《战争中的演艺圈》(1943年), 奥森·威尔斯(Orson Welles)和杰克·尼科尔森(Jack Nicholson)一起在《安全的地方》(A Safe Place)(1971年)中, 杰克·尼科尔森(Jack Nicholson)和凯文·培根(Kevin Bacon)一起出演了《好男人》(A Few Good Men,1992)! 我正在尝试两种不同的方式,一种是给我一个空集,另一种是给我这个错误信息“递归通用表表达式的完全选择 DBMASTER。 BACON”必须是两个或多个全选的UNION链接 且不得包含列函数,子句GROUP BY,HAVING 或ORDER BY仍包含带有CLAUSE ON的显式连接。'

WITH bacon (actorid, bacon_number) AS (
SELECT UNIQUE actorid, 0 FROM movies2actors 
        WHERE actorid =  (SELECT actorid FROM actors WHERE name = 'Bacon, Kevin (I)') UNION ALL
SELECT movies2actors.actorid, bacon.bacon_number + 1
FROM movies2actors, bacon 
       WHERE movies2actors.actorid IN 
            (SELECT UNIQUE actorid FROM movies2actors WHERE movieid IN (SELECT UNIQUE movieid FROM movies2actors 
                WHERE actorid = (SELECT actorid FROM actors WHERE name = 'Bacon, Kevin (I)') )) 
            AND movies2actors.actorid <> (SELECT actorid FROM actors WHERE name = 'Bacon, Kevin (I)') AND bacon.bacon_number<2  
)
SELECT bacon.actorid , bacon.bacon_number  FROM bacon ;

WITH bacon (actorid,relationid, bacon_number) AS (
SELECT UNIQUE actorid, actorid ,0 FROM ACTORS 
        WHERE name = 'Bacon, Kevin (I)'
UNION ALL
SELECT ACTORS.actorid,bacon.relationid, bacon.bacon_number + 1
FROM ACTORS
       JOIN  bacon ON ACTORS.actorid = bacon.relationid
       WHERE ACTORS.actorid IN 
            (SELECT UNIQUE actorid FROM movies2actors WHERE movieid IN (SELECT UNIQUE movieid FROM movies2actors 
                WHERE actorid = (SELECT actorid FROM actors WHERE name = 'Bacon, Kevin (I)') )) 
            AND ACTORS.actorid <> (SELECT actorid FROM actors WHERE name = 'Bacon, Kevin (I)') AND bacon.bacon_number<2     
)
SELECT bacon.actorid , bacon.bacon_number  FROM bacon ;

2 个答案:

答案 0 :(得分:0)

在可追溯的CTE中使用旧的联接语法(在Db2 LUW中)

table a,
table b
Where a.col = b.col 

答案 1 :(得分:0)

尝试一下:

#windowMasterMagnifyingGlass {
    float: none;
    margin-top: 1px;
    margin-right: 351px;
    cursor: pointer;
    margin: auto;
}


#windowMasterSearchBox, #windowMasterSearchBox {
    margin: auto;
    margin-bottom: 7px;
}

#windowSearchDiv {
    padding: 13px;
    display: block;
    text-align: center;
}
````[![The magnifying glass should be lower][1]][1]


  [1]: https://i.stack.imgur.com/DqtzM.png

您可以取消注释掉带有示例数据的注释块,然后按原样运行语句以检查结果。
/* WITH Movies (movieid, moviename) AS ( VALUES (1, 'Show Business at War (1943)') , (2, 'A Safe Place (1971)') , (3, 'A Few Good Men (1992)') ) , Actors (actorid, actorname) AS ( VALUES (1, 'Alfred Hitchcock') , (2, 'Orson Welles') , (3, 'Jack Nicholson') , (4, 'Kevin Bacon') ) , Movies2Actors (movieid, actorid) AS ( VALUES (1, 1) , (1, 2) , (2, 2) , (2, 3) , (3, 3) , (3, 4) ) , */ bacon (actorid, level, chain) AS ( SELECT mo.actorid, 1, cast('|'||trim(a.actorid)||'|'||trim(mo.actorid)||'|' AS varchar(1000)) FROM Actors a, Movies2Actors mb, Movies2Actors mo WHERE a.actorname= 'Kevin Bacon' --'Jack Nicholson' --'Orson Welles' AND a.actorid=mb.actorid AND mb.movieid=mo.movieid AND a.actorid<>mo.actorid UNION ALL SELECT mo.actorid, b.level+1, b.chain||trim(mo.actorid)||'|' FROM bacon b, Movies2Actors mb, Movies2Actors mo WHERE b.actorid=mb.actorid AND mb.movieid=mo.movieid AND locate('|'||trim(mo.actorid)||'|', b.chain)=0 ) SELECT DISTINCT a.actorname --, b.* FROM bacon b JOIN Actors a ON a.actorid=b.actorid; 列是为了防止递归。

相关问题