1

私はこのようなテーブルを持っています:

table item
(
   id    int,
   quantity float,
   father int, -- refer to item itself in case of subitem
)

私はこのようにすべての量と息子の量を合計する必要があります:

select i.id, max(i.quantity)+sum(ft.quantity) as quantity
from item i
left join item ft on ft.id=i.id
group by i.id

私の悩みは、父と息子の関係が再帰的であるため、祖父の量なども合計したいのですが…何度も参加できないので、最大の深さはわかりません。

私に何ができる?ありがとうございました。

4

2 に答える 2

2

再帰CTEを使用する必要があります。このようなもの:

;WITH FathersSonsTree
AS
(
  SELECT Id, quantity, 0 AS Level
  FROM Items WHERE fatherid IS NULL
  UNION ALL
  SELECT c.id, c.quantity, p.level+1
  FROM FathersSonsTree p
  INNER JOIN items c ON c.fatherid = p.id
 ), ItemsWithMaxQuantities
AS
(
  SELECT *,
  ROW_NUMBER() OVER(PARTITION BY level 
                    ORDER BY quantity DESC) rownum
  FROM FathersSonsTree
  )
SELECT 
  ID,  
  (SELECT MAX(Quantity) 
   FROM FathersSonsTree t3 
   WHERE t3.level = t1.level
  ) + 
  ISNULL((SELECT SUM(t2.Quantity) 
   FROM FathersSonsTree t2
   WHERE t1.level - t2.level = 1), 0)
FROM FathersSonsTree t1
ORDER BY ID;

SQLフィドルデモ

これにより、次のようなものが得られます。

| ID | QUANTITY |
-----------------
|  1 |       10 |
|  2 |       20 |
|  3 |       20 |
|  4 |       20 |
|  5 |       32 |
|  6 |       32 |
|  7 |       32 |
|  8 |       32 |
于 2012-12-11T16:01:25.703 に答える
0

SQLAuthority に関するこの記事で説明されているように、再帰的な CTE (共通テーブル式) を作成してみてください。

http://blog.sqlauthority.com/2012/04/24/sql-server-introduction-to-hierarchical-query-using-a-recursive-cte-a-primer/

著者の Pinal Dave は、ManagerID の自己参照外部キーを持つ従業員テーブルで再帰 CTE を使用して、従業員のリストと従業員が所属する階層の最上位との間にあるレベル数のカウントを返すことについて説明しています。マネージャーなし (ManagerID = NULL)。それはまさにあなたが望んでいるものではありませんが、それはあなたを始めるかもしれません.

私は少し実験を行い、Mahmoud Gamal のソリューションに非常に似たものになりましたが、親、祖父母、曽祖父母などの量だけでなく子の量も含めるというわずかな違いがあります。

使用したテストテーブルは次のとおりです。

CREATE TABLE Items(ID int IDENTITY
                      CONSTRAINT PK_Items PRIMARY KEY,
               Quantity int NOT NULL,
               ParentID int NULL
                            CONSTRAINT FK_Item_Parents REFERENCES Items(ID));

そしてデータ:

ID 数量 ParentID            
-------------------------------------------------- ----------
1 10 {ヌル}
2 10 1
3 10 2
4 10 3
5 10 2

これが私の再帰クエリです:

WITH cteRecursiveItems
AS (SELECT Id,
           quantity,
           0
          AS Level
    FROM Items
    WHERE ParentID IS NULL
    UNION ALL
    SELECT i.id,
           i.quantity,
           cri.level + 1
    FROM
         cteRecursiveItems cri
         INNER JOIN items i ON i.ParentID = cri.id)
SELECT ID,
       Quantity + (
                   SELECT MAX(Quantity)
                   FROM cteRecursiveItems cri3
                   WHERE cri3.level = cri1.level) + (
                                                 SELECT SUM(cri2.Quantity)
                                                 FROM cteRecursiveItems cri2
                                                 WHERE cri1.level - cri2.level = 1) as Total
FROM cteRecursiveItems cri1
ORDER BY ID;

テストテーブルに対して実行した結果は次のとおりです。

ID合計             
--------------------------------------------
1 {ヌル}
2 30
3 30
4 40
5 30

1 行目と 2 行目が 10 ずれているので、まだ少し調整が必要です。1 行目の合計は 10 で、2 行目の合計は 20 になるはずです。 . 今のところ、雇用主の時間の多くをこれに費やすことはできません。:) 他の行には、私が期待していた値があります。

于 2012-12-11T16:38:52.777 に答える