AnO*_*oul 8 cte t-sql subquery sql-server-2012
我有一个名为的表Category
,其中有一列名为CategoryID
. 同一个表中有一个引用列,称为fParentCategoryID
。
我需要将所有类别 ID 及其子类别 ID 以逗号分隔。例如 -如果 10 的父类别 ID 为 1,如果 20 的父类别 ID 为 10,那么当我打印类别 ID 20 时,我需要以逗号分隔值打印 1 和 10 作为其父项。
我尝试了以下查询,但我得到NULL
了ParChild
列。请帮忙。
;WITH
cteReports
AS
(
SELECT c.CategoryID,
c.fParentCategoryID,
[level] = 1,
ParChild=cast(CAST(c.fParentCategoryID AS VARCHAR(200)) + ',' + CAST(c.CategoryID AS VARCHAR(200)) AS VARCHAR(MAX))
FROM retail.Category c
WHERE c.fParentCategoryID is NULL
UNION ALL
SELECT c.CategoryID,
c.fParentCategoryID,
[level] + 1,
ParChild = ParChild + ',' + CAST(c.CategoryID AS VARCHAR(200))
FROM retail.Category c
JOIN cteReports r
ON c.fParentCategoryID = r.CategoryID
)
SELECT *
FROM cteReports cr
Run Code Online (Sandbox Code Playgroud)
使用此脚本创建和填充表。 (注意:问题正文有 30K 的限制..所以我不得不使用 pastebin 复制你的代码并引用它)
我能够用您的示例数据复制您的结果。
您的问题是,在递归 CTE(第一个 select 语句)的“基本”情况下,您将获取 fParentCategoryID 为 null 的记录,并将 fParentCategoryID 转换为准备附加“子项”的字符列。然而,在此阶段“字符串”仍然是 NULL 值(尝试使用 SELECT CAST(NULL AS VARCHAR(200)) 等)。
然后,第二个 select 语句尝试将其他字符串值附加到 NULL,但默认情况下,数据库选项“concat null 产生 null”表示,如果您尝试将任何内容连接到 NULL 值,那么您仍然只会得到 NULL - 而不是将其视为一个空字符串。
您可以为此查询设置 CONCAT_NULL_YIELDS_NULL OFF,尽管这已被弃用,并且最终将在 SQL Server 的未来版本中删除(因此您可能不应该将其添加到生产代码中!)
更好的方法是在第一个 select 语句中,不要将 fParentCategoryID 转换为字符串,而只需转换 CategoryID - 我们已经知道父级应该为空,因为它们是 NULL。
SELECT c.CategoryID,
c.fParentCategoryID,
[level] = 1,
ParChild=cast(CAST(c.CategoryID AS VARCHAR(200)) AS VARCHAR(MAX))
FROM retail.Category c
WHERE c.fParentCategoryID is NULL
Run Code Online (Sandbox Code Playgroud)
如果您的数据在该 select 语句中可能混合存在 null 和非 null 值,则还可以在其周围使用 ISNULL 将任何 null 视为空字符串。
当您获得诸如“,461,464”之类的值时,它可能需要对其生成的 ParChild 值进行一些清理,因此您可能需要去掉开头的逗号。
归档时间: |
|
查看次数: |
1074 次 |
最近记录: |