簡體   English   中英

用於計算小計和總計的 SQL 查詢

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM