尝试用 JOIN 替换交叉应用
Trying to replace a Cross Apply with a JOIN
我们有一个table,ProductHierarchy
,这是设置好的。行数不会改变。它包含简单的 parent/child 产品层次结构数据。
我们还有一个 Table 值函数,它接受 ProductHierarchyId
然后 returns 所有行,其中 IsDescendantOf 对于该 ID 为真。或者换句话说,它 returns 那一行,加上它的所有祖先。
问题是,对于这个 Table 值的函数,我们必须将它与 CROSS APPLY
一起使用,这会严重减慢查询速度。
我的想法是创建第二个永久 table(或相关查询中的临时 table/table 变量),它具有 Table 值函数的所有可能结果已经在里面了。然后 JOIN
到那个 table 而不是使用 CROSS APPLY
。在此 table 中,我们将添加一个名为 QueryID
的列。所以而不是
CROSS APPLY dbo.GetProductLevels(P.ProductHierarchyId)
我们可以使用
LEFT JOIN FutureTable ft ON ft.QueryId = P.ProductHierarchyId
我正在努力创建 table 的查询。这是我目前所拥有的...
SELECT
*
, 1 AS QueryId
FROM
dbo.ProductHierarchy
WHERE
(SELECT ProductHierarchyNode FROM dbo.ProductHierarchy WHERE ProductHierarchyId = 1).IsDescendantOf(ProductHierarchyNode) = 1
好的,这对于 ProductHierarchyId = 1 的记录非常有效。但是我需要为 ProductHierarchyId = 2 重复该操作:
SELECT
*
, 2 AS QueryId
FROM
dbo.ProductHierarchy
WHERE
(SELECT ProductHierarchyNode FROM dbo.ProductHierarchy WHERE ProductHierarchyId = 2).IsDescendantOf(ProductHierarchyNode) = 1
然后是 3,然后是 4,一直到最后一个 Id,每次都在一个循环内执行 UNION
——这太可怕了。
我知道有一种方法可以在一个查询中完成这一切。类似于递归 CTE。但是我的大脑还没有到达那里。
你不就这样吗?
SELECT . . . -- the columns you want
INTO . . . -- where you want them
FROM dbo.ProductHierarchy ph CROSS APPLY
dbo.GetProductLevels(P.ProductHierarchyId);
我们有一个table,ProductHierarchy
,这是设置好的。行数不会改变。它包含简单的 parent/child 产品层次结构数据。
我们还有一个 Table 值函数,它接受 ProductHierarchyId
然后 returns 所有行,其中 IsDescendantOf 对于该 ID 为真。或者换句话说,它 returns 那一行,加上它的所有祖先。
问题是,对于这个 Table 值的函数,我们必须将它与 CROSS APPLY
一起使用,这会严重减慢查询速度。
我的想法是创建第二个永久 table(或相关查询中的临时 table/table 变量),它具有 Table 值函数的所有可能结果已经在里面了。然后 JOIN
到那个 table 而不是使用 CROSS APPLY
。在此 table 中,我们将添加一个名为 QueryID
的列。所以而不是
CROSS APPLY dbo.GetProductLevels(P.ProductHierarchyId)
我们可以使用
LEFT JOIN FutureTable ft ON ft.QueryId = P.ProductHierarchyId
我正在努力创建 table 的查询。这是我目前所拥有的...
SELECT
*
, 1 AS QueryId
FROM
dbo.ProductHierarchy
WHERE
(SELECT ProductHierarchyNode FROM dbo.ProductHierarchy WHERE ProductHierarchyId = 1).IsDescendantOf(ProductHierarchyNode) = 1
好的,这对于 ProductHierarchyId = 1 的记录非常有效。但是我需要为 ProductHierarchyId = 2 重复该操作:
SELECT
*
, 2 AS QueryId
FROM
dbo.ProductHierarchy
WHERE
(SELECT ProductHierarchyNode FROM dbo.ProductHierarchy WHERE ProductHierarchyId = 2).IsDescendantOf(ProductHierarchyNode) = 1
然后是 3,然后是 4,一直到最后一个 Id,每次都在一个循环内执行 UNION
——这太可怕了。
我知道有一种方法可以在一个查询中完成这一切。类似于递归 CTE。但是我的大脑还没有到达那里。
你不就这样吗?
SELECT . . . -- the columns you want
INTO . . . -- where you want them
FROM dbo.ProductHierarchy ph CROSS APPLY
dbo.GetProductLevels(P.ProductHierarchyId);