tsql 递归选择

发布于 2025-01-08 17:47:46 字数 369 浏览 0 评论 0原文

我有一个表,其下一个结构

Id|State|Quan|SellQuan|LastId
3 |2    | 5  | 0      |2
2 |3    |10  | 5      |1
1 |3    |15  | 5      |NULL

LastId 在 Id 字段上引用,我需要在下一步中计算值:从 Id=3 中获取 Quan,然后添加所有在先前 LastId 上引用的 Id 的 sellquan。就是这样 Id=3 - 最后一个Id = 2 =>从 Id=2 字段 sellquan 中获取值,然后检查 LastId 是否不为空 .在我的例子中LastId = 1 =>取Id=1值SellQaun 结果:5 + 5+ 5 = 15

I have a table with next structure

Id|State|Quan|SellQuan|LastId
3 |2    | 5  | 0      |2
2 |3    |10  | 5      |1
1 |3    |15  | 5      |NULL

LastId is referenced on Id field, I need calulate value on next step: take Quan from Id=3 then add all sellquan with Id referenced on previous LastId. thats meen
Id=3 - lastId = 2 => take value from Id=2 field sellquan then chek if lastId is not null
.In my ecample LastId = 1 => Take Id=1 value SellQaun
Result: 5 + 5+ 5 = 15

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

遮了一弯 2025-01-15 17:47:46

我不太确定你想要什么。但我会尝试一下。

首先是一些测试数据:

DECLARE @tbl TABLE(Id INT,State INT,Quan INT,SellQuan INT,LastId INT)
INSERT INTO @tbl
VALUES
    (3,2,5,0,2),
    (2,3,10,5,1),
    (1,3,15,5,NULL)

然后是这样的递归函数:

DECLARE @Id INT=1
;WITH CTE(Id,parentId,SellQuan,topParent)
AS
(
    SELECT
        tbl.Id,
        tbl.LastId AS parentId,
        (CASE 
            WHEN EXISTS(SELECT NULL FROM @tbl AS tbl2 WHERE tbl2.LastId=tbl.Id)
            THEN tbl.SellQuan
            ELSE tbl.Quan
        END) AS SellQuan,
        tbl.Id AS topParent
    FROM
        @tbl AS tbl
    WHERE
        tbl.Id=@Id
    UNION ALL
    SELECT
        tbl.Id,
        tbl.LastId AS parentId,
        (CASE 
            WHEN EXISTS(SELECT NULL FROM @tbl AS tbl2 WHERE tbl2.LastId=tbl.Id)
            THEN tbl.SellQuan
            ELSE tbl.Quan
        END) AS SellQuan,
        CTE.topParent AS topParent
    FROM
        @tbl AS tbl
        JOIN CTE
            ON CTE.Id=tbl.LastId
)
SELECT
    CTE.topParent AS id,
    SUM(CTE.SellQuan) AS SellQaunResult
FROM
    CTE
GROUP BY
    CTE.topParent

希望这有帮助

I am not really sure what you want. But I will give it a try.

First some test data:

DECLARE @tbl TABLE(Id INT,State INT,Quan INT,SellQuan INT,LastId INT)
INSERT INTO @tbl
VALUES
    (3,2,5,0,2),
    (2,3,10,5,1),
    (1,3,15,5,NULL)

Then the recursive function like this:

DECLARE @Id INT=1
;WITH CTE(Id,parentId,SellQuan,topParent)
AS
(
    SELECT
        tbl.Id,
        tbl.LastId AS parentId,
        (CASE 
            WHEN EXISTS(SELECT NULL FROM @tbl AS tbl2 WHERE tbl2.LastId=tbl.Id)
            THEN tbl.SellQuan
            ELSE tbl.Quan
        END) AS SellQuan,
        tbl.Id AS topParent
    FROM
        @tbl AS tbl
    WHERE
        tbl.Id=@Id
    UNION ALL
    SELECT
        tbl.Id,
        tbl.LastId AS parentId,
        (CASE 
            WHEN EXISTS(SELECT NULL FROM @tbl AS tbl2 WHERE tbl2.LastId=tbl.Id)
            THEN tbl.SellQuan
            ELSE tbl.Quan
        END) AS SellQuan,
        CTE.topParent AS topParent
    FROM
        @tbl AS tbl
        JOIN CTE
            ON CTE.Id=tbl.LastId
)
SELECT
    CTE.topParent AS id,
    SUM(CTE.SellQuan) AS SellQaunResult
FROM
    CTE
GROUP BY
    CTE.topParent

Hope this helps

爱给你人给你 2025-01-15 17:47:46

根据您的要求,我认为您的示例表中有错字。如果您对以下内容进行更改,则会改变 CTE 的复杂性:

Id|State|Quan|SellQuan|LastId
3 |2    | 5  | 5      |2
2 |3    |10  | 5      |1
1 |3    |15  | 5      |NULL

我进行该更改,它会简化 CTE。

DECLARE @tbl TABLE(Id INT,State INT,Quan INT,SellQuan INT,LastId INT)
INSERT INTO @tbl
VALUES
(3,2,5,5,2),
(2,3,10,5,1),
(1,3,15,5,NULL);

;WITH CTE(Id,total,depth)
AS (
SELECT tbl.Id, SellQuan as total, 0 as depth
  FROM @tbl AS tbl
 WHERE tbl.LastId is null
 UNION ALL -- Recursive part of the query
SELECT tbl.Id,
       tbl.SellQuan + CTE.total,
       CTE.depth + 1 as depth
  FROM @tbl AS tbl
 INNER JOIN CTE ON CTE.Id = tbl.LastId
)
SELECT top 1 total
FROM CTE
order by depth desc;

我希望这有帮助。有关 CTE 的更多信息,我的网站上有几篇文章:
http://stevestedman.com/cte/

Based on what you are asking for, I think you have a typo in your sample table. If you make a change to the following it changes the complexity of the CTE:

Id|State|Quan|SellQuan|LastId
3 |2    | 5  | 5      |2
2 |3    |10  | 5      |1
1 |3    |15  | 5      |NULL

My making that change, it simplifies the CTE.

DECLARE @tbl TABLE(Id INT,State INT,Quan INT,SellQuan INT,LastId INT)
INSERT INTO @tbl
VALUES
(3,2,5,5,2),
(2,3,10,5,1),
(1,3,15,5,NULL);

;WITH CTE(Id,total,depth)
AS (
SELECT tbl.Id, SellQuan as total, 0 as depth
  FROM @tbl AS tbl
 WHERE tbl.LastId is null
 UNION ALL -- Recursive part of the query
SELECT tbl.Id,
       tbl.SellQuan + CTE.total,
       CTE.depth + 1 as depth
  FROM @tbl AS tbl
 INNER JOIN CTE ON CTE.Id = tbl.LastId
)
SELECT top 1 total
FROM CTE
order by depth desc;

I hope this helps. For more info on CTE's I have several articles on my website:
http://stevestedman.com/cte/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文