Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server:CTE(递归),在CTE之外设置条件_Sql_Sql Server 2008_Recursion_Common Table Expression - Fatal编程技术网

SQL Server:CTE(递归),在CTE之外设置条件

SQL Server:CTE(递归),在CTE之外设置条件,sql,sql-server-2008,recursion,common-table-expression,Sql,Sql Server 2008,Recursion,Common Table Expression,使用下面的查询(我是CTE新手,所以这可能会很混乱),我希望为数据库中的所有最终类别构建一个反向类别路径 目前,我在CTE本身中定义了一个ID(268707)。在我最后的主查询中,有没有一种方法可以在引用CTE时提供一个变量 我已经在查询中添加了一条注释,我认为这是进行此操作的理想位置,但我一生都不知道如何进行此操作 WITH recursion(stocknode_id, short_desc, parentnode_id, level) AS ( SELECT stocknode_i

使用下面的查询(我是CTE新手,所以这可能会很混乱),我希望为数据库中的所有最终类别构建一个反向类别路径

目前,我在CTE本身中定义了一个ID(268707)。在我最后的主查询中,有没有一种方法可以在引用CTE时提供一个变量

我已经在查询中添加了一条注释,我认为这是进行此操作的理想位置,但我一生都不知道如何进行此操作

WITH recursion(stocknode_id, short_desc, parentnode_id, level) AS
(
SELECT
    stocknode_id,
    short_desc,
    parentnode_id,
    0 AS level

FROM stock_website_node AS swn

WHERE swn.stocknode_id = 268707

UNION ALL

SELECT
    swn.stocknode_id,
    swn.short_desc,
    swn.parentnode_id,
    h.level + 1

FROM stock_website_node AS swn

INNER JOIN recursion AS h ON h.parentnode_id = swn.stocknode_id
)

SELECT
TOP 1 STUFF
(
    (
        SELECT ' / ' + swn_stuff.short_desc
        FROM stock_website_node AS swn_stuff
        WHERE swn_stuff.stocknode_id IN (SELECT stocknode_id FROM recursion) /* <--- I want to pass the variable from here, I think... */
        FOR XML PATH(''), TYPE
    ).value('.','varchar(max)'),
    1, 2, ''
 ) AS category_tree

FROM stock_website_node AS swn_a
我已经用SQL创建了一个代码板来创建一个表变量,这样如果您想运行代码(),您就可以确切地看到我在做什么

该表包含类别,parentnode_id指父类别的stocknode_id。parentnode_id为0表示这是顶级类别。当前在CTE中提供的变量是一个底层类别,查询将整体构建一个类别路径作为结果,例如:

顶级/二级/三级/四级


在主查询过程中,我想提供几个底层类别,并返回每个类别的类别路径,但当前的限制是只能手动定义一个底层ID,而不能动态提供几个,我有点卡住了。

在执行查询之前,用变量替换CTE中的常量值,并为变量赋值

不能从代码中注释的位置向CTE传递值。在整个查询之前,必须将该值分配给变量

declare @v int;
set @v = 268707;

with ....
(
  select ...
  where swn.stocknode_id = @v
  union all
  select ...
)
select ...
如果要指定多个stocknode_id,可以添加一个表变量来保存所需的值,并在如下查询中使用:

declare @T table(stocknode_id int);
insert into @T values(8), (12);

with R as 
(
  select C.stocknode_id, 
         cast(C.short_desc as varchar(max)) as short_desc,
         C.parentnode_id
  from @categories as C
  where C.stocknode_id in (select T.stocknode_id from @T as T)
  union all
  select C.stocknode_id,
         C.short_desc + ' / ' +  R.short_desc,
         C.parentnode_id
  from @categories as C
    inner join R  
      on C.stocknode_id = R.parentnode_id
)
select R.short_desc
from R
where R.parentnode_id = 0;

当然,您与任何其他查询都有相同的选项。我在从
swn_a
中选择时尝试使用变量,但出现了错误:
为变量赋值的SELECT语句不能与数据检索操作结合使用。
您应该在执行查询之前为变量赋值。啊,我这里的问题是,我希望动态设置变量,即
@var=swn_a.stocknode_id
@Ben,在第二个查询中,我想您可以将整个where子句移动到递归CTE的锚定部分。如果没有,那么我真的不理解您的表结构和查询的作用。如果您希望帮助将查询重写为能够正常工作并执行所需操作的内容,则需要将表结构、示例数据和预期输出添加到问题中。我已更新了我的问题,您可以在此处找到更好的表结构示例:-感谢您的帮助
declare @T table(stocknode_id int);
insert into @T values(8), (12);

with R as 
(
  select C.stocknode_id, 
         cast(C.short_desc as varchar(max)) as short_desc,
         C.parentnode_id
  from @categories as C
  where C.stocknode_id in (select T.stocknode_id from @T as T)
  union all
  select C.stocknode_id,
         C.short_desc + ' / ' +  R.short_desc,
         C.parentnode_id
  from @categories as C
    inner join R  
      on C.stocknode_id = R.parentnode_id
)
select R.short_desc
from R
where R.parentnode_id = 0;