[英]SQL query to calculate subtotal and grand total
我有以下示例數據:
TimeSheetID RosterID EmpID RosterDate StartTime EndTime Total
1 101 1001 2016-05-24 07:00 15:00 8
2 101 1001 2016-05-24 16:00 21:00 5
3 101 1002 2016-05-24 07:00 15:00 8
4 101 1003 2016-05-24 07:00 15:00 8
5 101 1001 2016-05-25 07:00 15:00 8
6 101 1002 2016-05-25 07:00 15:00 8
7 101 1002 2016-05-25 16:00 22:00 6
8 101 1003 2016-05-25 07:00 15:00 8
9 101 1001 2016-05-26 07:00 14:00 7
10 101 1001 2016-05-26 15:00 21:00 6
11 101 1002 2016-05-26 07:00 15:00 8
12 101 1003 2016-05-26 07:00 15:00 8
13 101 1001 2016-05-27 07:00 15:00 8
14 101 1002 2016-05-27 07:00 15:00 8
15 101 1003 2016-05-27 07:00 15:00 8
16 101 1001 2016-05-28 07:00 15:00 8
17 101 1002 2016-05-28 07:00 15:00 8
18 101 1003 2016-05-28 07:00 15:00 8
19 101 1001 2016-05-29 07:00 15:00 8
20 101 1002 2016-05-29 07:00 15:00 8
21 101 1003 2016-05-29 07:00 15:00 8
22 102 1001 2016-05-30 07:00 15:00 8
我想生產:
ID RosterID EmpID RosterDate StartTime EndTime Total
1 101 1001 2016-05-24 07:00 15:00 8
2 101 1001 2016-05-24 16:00 21:00 5
3 101 1001 2016-05-24 Null Null 13
4 101 1002 2016-05-24 07:00 15:00 8
5 101 1003 2016-05-24 07:00 15:00 8
6 101 1001 2016-05-25 07:00 15:00 8
7 101 1002 2016-05-25 07:00 15:00 8
8 101 1002 2016-05-25 16:00 22:00 6
9 101 1002 2016-05-25 Null Null 14
10 101 1003 2016-05-25 07:00 15:00 8
11 101 1001 2016-05-26 07:00 14:00 7
12 101 1001 2016-05-26 15:00 21:00 6
13 101 1001 2016-05-26 Null Null 13
14 101 1002 2016-05-26 07:00 15:00 8
15 101 1003 2016-05-26 07:00 15:00 8
16 101 1001 2016-05-27 07:00 15:00 8
17 101 1002 2016-05-27 07:00 15:00 8
18 101 1003 2016-05-27 07:00 15:00 8
19 101 1001 2016-05-28 07:00 15:00 8
20 101 1002 2016-05-28 07:00 15:00 8
21 101 1003 2016-05-28 07:00 15:00 8
22 101 1001 2016-05-29 07:00 15:00 8
23 101 1002 2016-05-29 07:00 15:00 8
24 101 1003 2016-05-29 07:00 15:00 8
25 102 1001 2016-05-30 07:00 15:00 8
26 Total Null Null Null Null 168
我想使用 SQL Query RollUp 語句獲取示例輸出,因為性能是問題。 由於時間表表將有數百萬條記錄。 有沒有其他方法可以代替視圖來執行此編寫過程或函數? 提前感謝您的幫助 Ishwor
我認為您不能將結果與同一個表中的數據混合。 另外,如果這是可能的,我認為這不是一個好主意。
您可以使用類似於此的查詢獲取小計:
select RosterID, EmpID, RosterDate, sum(Total)
from tableRoster group by RosterID, EmpID, RosterDate;
總數更容易,您可以通過以下方式獲得:
select sum(Total) from tableRoster;
我嘗試使用你喜歡的方法......盡管可能有一些問題需要解決。 如果它沒有像預期的那樣 100% 工作,請道歉,但也許您可以采用以下內容並根據您的需要對其進行修改。
我懷疑在那里包含開始/結束日期會導致可以忽略的微不足道的子分組。 我意識到不完全測試我的解決方案對於這個論壇來說並不理想......對此感到抱歉......只是一時興起,以分散工作的注意力。 祝你好運。
SELECT
CASE WHEN (GROUPING(RosterID) = 1) THEN 'Total'
ELSE RosterID
END AS RosterID
,CASE WHEN (GROUPING(EmpID) = 1) AND (GROUPING(RosterID) = 1) THEN NULL
ELSE EmpID
END AS EmpID
,CASE WHEN (GROUPING(RosterDate) = 1) AND (GROUPING(RosterID) = 1) THEN NULL
ELSE RosterDate
END AS RosterDate
,CASE WHEN (GROUPING(RosterDate) = 1) THEN NULL
ELSE StartTime
END AS StartTime
,CASE WHEN (GROUPING(RosterDate) = 1) THEN NULL
ELSE EndTime
END AS EndTime
,Sum(Total) AS Total
FROM Table a
GROUP BY
ROLLUP(RosterID ,RosterDate ,EmpID ,StartTime ,EndTime)
ORDER BY
RosterID, RosterDate, EmpID
I tried to resolve with basic loop as below
-- ASSUMED THAT DATA IS INSERTED INTO Roster TABLE
-- STP_01: BY SEEING DATA COLUMNS ARE CREATED AS BELOW
CREATE TABLE Roster(TimeSheetID INT IDENTITY(1,1),RosterID INT ,EmpID INT , RosterDate DATE ,StartTime TIME, EndTime TIME, Total INT)
SET IDENTITY_INSERT Roster ON
GO
-- STP_02:INSERTING PROVIDED DATA AS BELOW
INSERT INTO Roster(TimeSheetID,RosterID,EmpID,RosterDate,StartTime,EndTime,Total)
VALUES(1 ,101,1001,'2016-05-24','07:00', '15:00', 8),
(2 ,101,1001,'2016-05-24','16:00', '21:00', 5),
(3 ,101,1002,'2016-05-24','07:00', '15:00', 8),
(4 ,101,1003,'2016-05-24','07:00', '15:00', 8),
(5 ,101,1001,'2016-05-25','07:00', '15:00', 8),
(6 ,101,1002,'2016-05-25','07:00', '15:00', 8),
(7 ,101,1002,'2016-05-25','16:00', '22:00', 6),
(8 ,101,1003,'2016-05-25','07:00', '15:00', 8),
(9 ,101,1001,'2016-05-26','07:00', '14:00', 7),
(10,101,1001,'2016-05-26','15:00', '21:00', 6),
(11,101,1002,'2016-05-26','07:00', '15:00', 8),
(12,101,1003,'2016-05-26','07:00', '15:00', 8),
(13,101,1001,'2016-05-27','07:00', '15:00', 8),
(14,101,1002,'2016-05-27','07:00', '15:00', 8),
(15,101,1003,'2016-05-27','07:00', '15:00', 8),
(16,101,1001,'2016-05-28','07:00', '15:00', 8),
(17,101,1002,'2016-05-28','07:00', '15:00', 8),
(18,101,1003,'2016-05-28','07:00', '15:00', 8),
(19,101,1001,'2016-05-29','07:00', '15:00', 8),
(20,101,1002,'2016-05-29','07:00', '15:00', 8),
(21,101,1003,'2016-05-29','07:00', '15:00', 8),
(22,102,1001,'2016-05-30','07:00', '15:00', 8)
SET IDENTITY_INSERT Roster OFF
GO
-- STP_03:CREATING Roster_1 TABLE TO INSERT PROCESSED DATA - NOT TOUCHING ORIGINAL TABLE
-- DROP TABLE Roster_1
CREATE TABLE [dbo].[Roster_1](
[TimeSheetID] [int] NULL,
[RosterID] [varchar](15) NULL, -- CHANGED TO VARCHAR(15) TO PROVIDE GrpToal/GndTotal
[EmpID] [varchar](15) NULL, -- CHANGED TO VARCHAR(15) TO PROVIDE GrpToal/GndTotal
[RosterDate] [date] NULL,
[StartTime] [time](7) NULL,
[EndTime] [time](7) NULL,
[Total] [int] NULL
)
-- STP_04: SOME VARIABLES TO PROCESS LOOP
DECLARE @MinRosterDate DATE,@MaxRosterDate DATE,@MinEmpId INT,@MaxEmpID INT,@kMinEmpId INT
SELECT
@MinRosterDate = MIN(RosterDate), -- 2016-05-24
@MaxRosterDate = MAX(RosterDate), -- 2016-05-30
@MinEmpId = MIN(EmpID), -- 1001
@MaxEmpID = MAX(EmpID) -- 1003
FROM Roster
-- STP_05: RE-RUNNABLE
TRUNCATE TABLE Roster_1
SET @kMinEmpId = @MinEmpId -- RESERVING THIS VALUE
-- STEP_06: ENTERING LOOP
WHILE (@MinRosterDate<= @MaxRosterDate) -- OUTER LOOP
BEGIN
WHILE(@MinEmpId <= @MaxEmpID) -- INNER LOOP FOR ALL EMPID WORKED DURING THIS TIME FRAME
BEGIN
IF EXISTS(SELECT 1 FROM Roster WHERE RosterDate = @MinRosterDate AND EmpID = @MinEmpId) -- CHECKING WHETHER DATA EXISTS
BEGIN
INSERT INTO Roster_1
SELECT TimeSheetID,CONVERT(VARCHAR(7),RosterID),CONVERT(VARCHAR(7),EmpID),RosterDate,StartTime,EndTime,Total FROM Roster WHERE RosterDate = @MinRosterDate AND EmpID = @MinEmpId
UNION
SELECT null,'GrpTotalByEmpID',@MinEmpId,@MinRosterDate,null,null,SUM(Total)FROM Roster WHERE RosterDate = @MinRosterDate AND EmpID = @MinEmpId
END
SET @MinEmpId = @MinEmpId + 1 -- BREAKING INNER LOOP
END
IF(@MinEmpId > @MaxEmpId) -- RESTARING FROM FIRST EmpID
SET @MinEmpId = @kMinEmpId
INSERT INTO Roster_1
SELECT null,null,'GrpTotalByDate',@MinRosterDate,null,null,SUM(Total) from Roster_1 where RosterID = 'GrpTotalByEmpID' and RosterDate = @MinRosterDate
IF(@MinRosterDate = @MaxRosterDate) -- CALCULATING Grand Total
BEGIN
INSERT INTO Roster_1
SELECT null,'GrandTotal',null,null,null,null,SUM(Total) FROM Roster_1 WHERE TimeSheetID IS NULL AND EmpID = 'GrpTotalByDate'
END
SET @MinRosterDate = DATEADD(DD,1, @MinRosterDate) -- BREAKING OUTER LOOP
END
-- STP_07: READING PROCESSED DATA
SELECT * FROM Roster_1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.