2016-09-19 17 views
2

Дана таблица T_BudgetCharts. Он содержит иерархическую структуру элементов от 1 до N-го уровня. Только элементы на N-ом уровне имеют назначенное значение. Другие предметы, которые не являются последним уровнем, имеют 0 assigend.SQL Query для получения сумм товаров в иерархической структуре между двумя таблицами

Другая таблица, T_Invoice. В этой таблице содержатся некоторые заказы, которые относятся к первой таблице, используя столбец BudgetItemID.

Что мне нужно, это написать SQL-запрос, который возвращает TotalSum каждого BudgetItem из T_BudgetCharts - включая сумму на каждом уровне, забронированную сумму за каждый элемент таблицы T_Invoice - (здесь возникает проблема) - в том числе забронированный сумма на каждом уровне в иерархии и сумма разностей, которая является разницей между первыми двумя значениями.

Я работаю на SQLSERVER 2008R2 ...

Изображение для лучшего понимания прилагается. Также SQL дамп ...

CREATE TABLE [dbo].[T_BudgetCharts](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [BudgetId] [int] NOT NULL, 
    [BudgetItemLevel] [int] NOT NULL, 
    [BudgetItemCode] [nvarchar](20) NOT NULL, 
    [BudgetItemName] [nvarchar](300) NOT NULL, 
    [BudgetItemMasterID] [int] NULL, 
    [BudgetItemBudegtValue] [decimal](18, 2) NULL, 
    [BugedtIdOriginal] [int] NULL, 
    [MasterIdOriginal] [int] NULL, 
    [BugedtItemStatus] [int] NOT NULL, 
    [sysDateTimeCreated] [datetime] NOT NULL, 
    [sysDateTimeModified] [datetime] NOT NULL, 
    CONSTRAINT [PK_T_BudgetCharts] PRIMARY KEY CLUSTERED 
    (
     [ID] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
    ) ON [PRIMARY] 

SET IDENTITY_INSERT [dbo].[T_BudgetCharts] ON 
INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (1, 1, 1, N'N/A', N'Not assigned', NULL, CAST(0.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CA5499 AS DateTime), CAST(0x0000A68000CA5499 AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (2, 1, 2, N'N/A', N'Not assigned', 1, CAST(0.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CA5499 AS DateTime), CAST(0x0000A68000CA5499 AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (3, 1, 3, N'N/A', N'Not assigned', 2, CAST(1000.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CA5499 AS DateTime), CAST(0x0000A68000CA7067 AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (4, 2, 1, N'N/A', N'Not assigned', NULL, CAST(0.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CA6213 AS DateTime), CAST(0x0000A68000CA6213 AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (5, 2, 2, N'N/A', N'Not assigned', 4, CAST(0.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CA6213 AS DateTime), CAST(0x0000A68000CA6213 AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (6, 2, 3, N'N/A', N'Not assigned', 5, CAST(0.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CA6213 AS DateTime), CAST(0x0000A68000CA6213 AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (7, 1, 1, N'A', N'Category A', NULL, CAST(0.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CA95BA AS DateTime), CAST(0x0000A68000CA95BA AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (8, 1, 2, N'100', N'Income', 7, CAST(0.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CAAEAF AS DateTime), CAST(0x0000A68000CAAEAF AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (9, 1, 2, N'200', N'Outcome', 7, CAST(0.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CAB852 AS DateTime), CAST(0x0000A68000CAB852 AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (10, 1, 3, N'A.100.1', N'Income 1', 8, CAST(2500.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CADF5F AS DateTime), CAST(0x0000A68000CB0545 AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (11, 1, 3, N'A.100.2', N'Income 2', 8, CAST(10000.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CAF466 AS DateTime), CAST(0x0000A68000CAF466 AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (13, 1, 3, N'A.200.1', N'Outcome 1', 9, CAST(6000.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CBB48C AS DateTime), CAST(0x0000A68000CBB48C AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (14, 1, 3, N'A.200.2', N'Other stuff', 9, CAST(3000.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CBC7EE AS DateTime), CAST(0x0000A68000CBC7EE AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (15, 2, 1, N'T1', N'Money', NULL, CAST(0.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CC2709 AS DateTime), CAST(0x0000A68000CC2709 AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (16, 2, 2, N'99', N'Type A', 15, CAST(0.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CC3E2C AS DateTime), CAST(0x0000A68000CC3E2C AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (17, 2, 2, N'98', N'Type B', 15, CAST(0.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CC4E48 AS DateTime), CAST(0x0000A68000CC4E48 AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (18, 2, 3, N'T1.98.1', N'B 1', 17, CAST(300.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CC698D AS DateTime), CAST(0x0000A68000CC698D AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (19, 2, 3, N'T1.98.2', N'B 2', 17, CAST(800.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CC73DB AS DateTime), CAST(0x0000A68000CC73DB AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (20, 2, 3, N'T1.99.1', N'A 1', 16, CAST(600.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CC958F AS DateTime), CAST(0x0000A68000CC958F AS DateTime)) 
    INSERT [dbo].[T_BudgetCharts] ([ID], [BudgetId], [BudgetItemLevel], [BudgetItemCode], [BudgetItemName], [BudgetItemMasterID], [BudgetItemBudegtValue], [BugedtIdOriginal], [MasterIdOriginal], [BugedtItemStatus], [sysDateTimeCreated], [sysDateTimeModified]) VALUES (21, 2, 3, N'T1.99.2', N'A 2', 16, CAST(400.00 AS Decimal(18, 2)), NULL, NULL, 1, CAST(0x0000A68000CCA173 AS DateTime), CAST(0x0000A68000CCA173 AS DateTime)) 
    SET IDENTITY_INSERT [dbo].[T_BudgetCharts] OFF 

CREATE TABLE [dbo].[T_Invoice](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [InvoiceBudgetingID] [int] NOT NULL, 
    [OrderNo] [int] NOT NULL, 
    [BudgetID] [int] NOT NULL, 
    [BudgetItemID] [int] NOT NULL, 
    [AmountProjectCurrency] [decimal](28, 16) NOT NULL, 
    [AmountBudgetCurrency] [decimal](28, 16) NOT NULL, 
    [BudgetCurrencyRate] [decimal](28, 16) NOT NULL, 
    [Percentage] [decimal](28, 16) NOT NULL, 
CONSTRAINT [PK_T_Invoice] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 


SET IDENTITY_INSERT [dbo].[T_Invoice] ON 
INSERT [dbo].[T_Invoice] ([ID], [InvoiceBudgetingID], [OrderNo], [BudgetID], [BudgetItemID], [AmountProjectCurrency], [AmountBudgetCurrency], [BudgetCurrencyRate], [Percentage]) VALUES (1, 1, 1, 1, 10, CAST(300.0000000000000000 AS Decimal(28, 16)), CAST(300.0000000000000000 AS Decimal(28, 16)), CAST(1.0000000000000000 AS Decimal(28, 16)), CAST(100.0000000000000000 AS Decimal(28, 16))) 
INSERT [dbo].[T_Invoice] ([ID], [InvoiceBudgetingID], [OrderNo], [BudgetID], [BudgetItemID], [AmountProjectCurrency], [AmountBudgetCurrency], [BudgetCurrencyRate], [Percentage]) VALUES (2, 2, 1, 1, 14, CAST(200.0000000000000000 AS Decimal(28, 16)), CAST(200.0000000000000000 AS Decimal(28, 16)), CAST(1.0000000000000000 AS Decimal(28, 16)), CAST(100.0000000000000000 AS Decimal(28, 16))) 
INSERT [dbo].[T_Invoice] ([ID], [InvoiceBudgetingID], [OrderNo], [BudgetID], [BudgetItemID], [AmountProjectCurrency], [AmountBudgetCurrency], [BudgetCurrencyRate], [Percentage]) VALUES (3, 2, 1, 1, 14, CAST(500.0000000000000000 AS Decimal(28, 16)), CAST(100.0000000000000000 AS Decimal(28, 16)), CAST(1.0000000000000000 AS Decimal(28, 16)), CAST(100.0000000000000000 AS Decimal(28, 16))) 
SET IDENTITY_INSERT [dbo].[T_Invoice] OFF 

**

CREATE TABLE [dbo].[T_Bookings](
     [ID] [int] IDENTITY(1,1) NOT NULL, 
     [BookingTypeID] [int] NOT NULL, 
     [ProjectID] [int] NOT NULL, 
     [InvoiceDate] [date] NOT NULL 
    CONSTRAINT [PK_T_Bookings] PRIMARY KEY CLUSTERED 
    (
     [ID] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
    ) ON [PRIMARY] 
    /****** Object: Table [dbo].[T_Bookings] Script Date: 09/21/2016 15:06:23 ******/ 
    SET IDENTITY_INSERT [dbo].[T_Bookings] ON 
    INSERT [dbo].[T_Bookings] ([ID], [BookingTypeID], [ProjectID], [InvoiceDate]) VALUES (1, 1, 1, CAST(0xCF3B0B00 AS Date)) 
    INSERT [dbo].[T_Bookings] ([ID], [BookingTypeID], [ProjectID], [InvoiceDate]) VALUES (2, 2, 1, CAST(0xCF3B0B00 AS Date)) 
    INSERT [dbo].[T_Bookings] ([ID], [BookingTypeID], [ProjectID], [InvoiceDate]) VALUES (3, 1, 1, CAST(0xCF3B0B00 AS Date)) 
    SET IDENTITY_INSERT [dbo].[T_Bookings] OFF 

**

enter image description here

До сих пор у меня есть первая часть, но не могу получить забронированы сумму и разность ... Вот мой текущий запрос ... Надеюсь, кто-то может помочь ...

WITH C AS 
(
    SELECT b.Id, 
      b.BudgetItemMasterID, 
      b.BudgetItemCode, 
      b.BudgetItemName, 
      b.BudgetItemBudegtValue, 
      b.BugedtItemStatus, 
      b.Id AS RootID 
    FROM T_BudgetCharts b 
    WHERE b.BugedtItemStatus = 1 
    UNION ALL 
    SELECT b.Id, 
      b.BudgetItemMasterID, 
      b.BudgetItemCode, 
      b.BudgetItemName, 
      b.BudgetItemBudegtValue, 
      b.BugedtItemStatus, 
      C.RootID 
    FROM T_BudgetCharts b 
    INNER JOIN C ON b.BudgetItemMasterID = C.Id 
    WHERE b.BugedtItemStatus = 1 
) 

SELECT b.ID as ID, 
     b.BudgetItemMasterID AS MasterID, 
     b.BudgetItemCode AS BudgetItemCode, 
     b.BudgetItemName AS BudgetItemName, 
     s.TotalValue AS TotalValue, 
     ISNULL(g.Spent, 0) as BookedSum, 
     0 as DifferenceSum --Not implemnted yet.. 
FROM T_BudgetCharts b 
INNER JOIN (SELECT RootID, SUM(BudgetItemBudegtValue) AS TotalValue FROM C GROUP BY RootID) AS s ON b.Id = s.RootID 
LEFT JOIN (SELECT BudgetItemId, SUM(AmountProjectCurrency) AS Spent FROM dbo.T_Invoice GRoup By BudgetItemId) AS g ON b.ID = g.BudgetItemID 
ORDER BY b.BudgetItemCode 
+0

@JohnCappelletti Что случилось с вашими ответами? – digestBen

+0

Вам просто нужно добавить группировку и суммы - я думаю, вы можете использовать что-то очень похожее на этот ответ: http://stackoverflow.com/questions/24394601/recursive-sum-in-tree-structure – SlimsGhost

+0

его немного сложнее , Пользователь @JohnCappelletti сегодня дал хороший ответ, но я не знаю, что произошло со всеми комментариями ... – digestBen

ответ

1

EDIT: (! Извините) фиксированное состояние присоединиться и некоторые другие детали

Следующая КТР соединяет каждую Id, как «корень» дерева, содержащего себя и всех детей от всех уровней). Запрос, использующий CTE, сворачивает НИЧЕГО, ЧТО ВЫ ХОТИТЕ, которое основано на группе (Id и все ее дети).

Я попытался заставить его выглядеть так же, как и ваша фотография, но вам все равно придется приспосабливать его к тому, что вам нужно. Ключевая часть использует CTE для определения каждой «группы» (каждого родителя и всех ее дочерних элементов).

WITH C AS 
(
    SELECT b.Id AS RootId, 
      b.BudgetItemMasterID as RootBudgetItemMasterID, 
      b.BudgetItemCode as RootBudgetItemCode, 
      b.BudgetItemName as RootBudgetItemName, 
      b.Id as ChildId 
    FROM T_BudgetCharts b 
    WHERE b.BugedtItemStatus = 1 
    UNION ALL 
    SELECT c.RootId, 
      c.RootBudgetItemMasterID, 
      c.RootBudgetItemCode, 
      c.RootBudgetItemName, 
      b.Id as ChildId 
    FROM T_BudgetCharts b 
    INNER JOIN C ON b.BudgetItemMasterID = C.ChildId 
    WHERE b.BugedtItemStatus = 1 
) 
SELECT 
    C.RootId as Id, 
    C.RootBudgetItemMasterID as BudgetItemMasterID, 
    C.RootBudgetItemCode as BudgetItemCode, 
    C.RootBudgetItemName as BudgetItemName, 
    sum(isnull(b.BudgetItemBudegtValue, 0)) AS TotalValue, 
    sum(isnull(g.AmountProjectCurrency, 0)) AS BookedSum, 
    sum(isnull(b.BudgetItemBudegtValue, 0)) - sum(isnull(g.AmountProjectCurrency, 0)) as DifferenceSum 
from C 
inner join T_BudgetCharts b ON b.Id = C.ChildId and b.BugedtItemStatus = 1 
left join T_Invoice g ON b.ID = g.BudgetItemID 
group by C.RootId, C.RootBudgetItemMasterID, C.RootBudgetItemCode, C.RootBudgetItemName 
order by C.RootId, C.RootBudgetItemMasterID, C.RootBudgetItemCode, C.RootBudgetItemName 
+0

Ваше решение не работает. Иерархические суммы не рассчитываются в BudgetCharts ни в счете-фактуре .... – digestBen

+0

взгляните на предоставленную картинку ... – digestBen

+0

Thats it. Выглядит хорошо для меня ... Thx – digestBen