SQL(MS 2008 r2)2の比較的単純なテーブルを合計すると、それを機能させる方法を見つけるのに苦労していますが、SQLの専門家の助けを借りてください:)
ツリータイプのテーブルを値のコレクションに結合します。ここでは、値の最新のインスタンス(外部キーx2ごと)のみを取得し、各値には作成日があり、作成日までに最新の値のみが必要です。また、最後に、ツリーの最下部にある値(つまり、子のない値)のみを合計したいと思います。私はCTEについて読み、これを機能させるための良い方法だと思いましたが、これまでにこれを行ったことがないので、私が書いたものを読むのに少し苦労しています:)
ノードと呼ばれる比較的単純なツリーテーブルがあります
[id] [int] IDENTITY(1,1) NOT NULL,
[parentID] [int] NOT NULL
私が興味を持っているこの表のデータは次のようなものです。(実際の単純な例では、最大で7レベルのネストの1000〜2000レコード、通常は3または4のレコードがあります)ID+ParentIDは常に一意です。
ID parentID
1077 1055
1110 1077
1103 1077
1104 1103
1105 1103
1111 1110
1112 1110
次に、これに結合したい他のテーブル割り当て。
[Id] [int] IDENTITY(1,1) NOT NULL,
[creation] [datetime] NULL,
[crewId] [int] NULL,
[mealId] [int] NULL,
[allocation] [int] NULL
ツリーに参加するのはcrewIdであり、これはパラメーターとして送信されるため、たとえば1077のすべての子の合計を取得します。子のない値の合計のみを含めたいと思います。私はmealIdの各値の合計が必要です。クルーID+ミールID+作成は常に一意です。
Id creation crewId mealId allocation
----------- ----------------------- ----------- ----------- -----------
1 2012-04-13 16:50:00.000 1111 1085 1
2 2012-04-13 16:55:00.000 1111 1085 3
3 2012-04-13 17:03:31.100 1111 1085 2
4 2012-04-18 22:35:21.790 1112 1085 1
5 2012-04-18 22:35:32.630 1112 1086 1
6 2012-04-18 22:35:42.473 1112 1087 1
7 2012-04-25 18:15:53.117 1111 1086 1
8 2012-04-25 19:11:46.227 1111 1085 1
9 2012-04-25 19:11:46.227 1110 1085 5
これは私がこれまでに持っているものです、
declare @crewId int
set @crewId = 1077
-- get total of allocated to childless children
;with
Recurse as (
select
n.Id as DirectChildId
, n.Id
from umbracoNode n
where parentId = @crewId
union all
select
b.DirectChildId
, n.Id
from umbracoNode n
join Recurse b on b.Id = n.ParentId
)
select
n.DirectChildId, mealId, sum(a.Allocation) as TotalAllocation
from Recurse n
left join Allocations a on n.Id = a.crewId
and a.CrewId not in (select parentId from umbracoNode)
group by DirectChildId, mealId;
これはほぼ機能しますが、最新の値を取得することはまだ考慮されていません。
現在最新バージョンを取得しているクエリは次のようになります。しかし、私はそれらを組み合わせる方法を理解することはできません。
SELECT a.mealId, a.allocation
FROM Allocations AS a
LEFT OUTER JOIN Allocations AS a2
ON (a2.crewId = @crewId and a.MealId = a2.MealId AND a2.creation < a2.creation)
WHERE a.crewId = @crewId and a2.crewId IS NULL;