每位员工的总计

时间:2015-01-20 17:21:50

标签: sql sql-server-2005

我有以下查询,可以很好地返回单个工作人员的累计拼车报销。 (员工每20次旅行赚30美元,旅行一直持续到年底)。

-- carpool quarter stats
use TRPTracking

declare @employeeID NVarChar(100), @year Char(4)
Set     @employeeID = 'PSmith'
Set     @year = '2014'
------
declare @startDate DateTime, @endDate DateTime
Set     @startDate = '1/1/' + @year
Set     @endDate = DateAdd(d,-1,DateAdd(yyyy,1,@startDate))

DECLARE @calendar TABLE (Date datetime)

WHILE (@startDate <= @endDate) BEGIN
    INSERT INTO @Calendar VALUES (@startDate)
    SET @startDate = DATEADD(quarter, 1, @startDate)
END

DECLARE @CarpoolTbl TABLE (quarter varchar(250), value decimal(18,1), runningTotal decimal(18,1), earned money)
DECLARE @runningTotal decimal(18,1), @earned money
SET @runningTotal = 0
SET @earned = 0

INSERT INTO @CarpoolTbl 
    SELECT CASE DatePart(q, c.date) 
        WHEN 1 THEN 'Jan-Mar' 
        WHEN 2 THEN 'Apr-Jun' 
        WHEN 3 THEN 'Jul-Sep' 
        WHEN 4 THEN 'Oct-Dec' END AS quarter,
        IsNULL(Sum(t.value),0) AS value,
        null,
        0
    FROM @calendar c
    LEFT OUTER JOIN events e ON (DatePart(q, c.date) = DatePart(q, e.eventDate) AND e.employeeID = @employeeID AND e.eventType = 'CP' AND Year(eventDate) = @year)
    LEFT JOIN types t ON t.typeID = e.eventType
    GROUP BY DatePart(q, c.date)

UPDATE @CarpoolTbl 
SET @earned = earned = Floor((@runningTotal + value)/20) - Floor(@runningTotal/20),
    @runningTotal = runningTotal = @runningTotal + value

FROM @CarpoolTbl

SELECT quarter, value, runningTotal, earned * 30 AS earned
FROM @CarpoolTbl

现在,我想要一个为所有员工返回此信息的查询。我删除了与employeeID相关的部分,我得到了看起来很好的东西。但是......正在发生的事情是我的跑步总数正在为所有人而战。我需要为每个员工重新启动它。我无法确定在运行总计中添加employeeID分组的位置。

-- carpool quarter stats
use TRPTracking

declare @year Char(4)
Set     @year = '2014'
------
declare @startDate DateTime, @endDate DateTime
Set     @startDate = '1/1/' + @year
Set     @endDate = DateAdd(d,-1,DateAdd(yyyy,1,@startDate))

DECLARE @calendar TABLE (Date datetime)

WHILE (@startDate <= @endDate) BEGIN
    INSERT INTO @Calendar VALUES (@startDate)
    SET @startDate = DATEADD(quarter, 1, @startDate)
END

DECLARE @CarpoolTbl TABLE (dateQ int, quarter varchar(250), employeeID varchar(255), value decimal(18,1), runningTotal decimal(18,1), earned money)
DECLARE @runningTotal decimal(18,1), @earned money
SET @runningTotal = 0
SET @earned = 0

INSERT INTO @CarpoolTbl 
    SELECT 
        DatePart(q, c.date),
        CASE DatePart(q, c.date) 
            WHEN 1 THEN 'Jan-Mar' 
            WHEN 2 THEN 'Apr-Jun' 
            WHEN 3 THEN 'Jul-Sep' 
            WHEN 4 THEN 'Oct-Dec' END AS quarter,
        e.employeeID,
        IsNULL(Sum(t.value),0) AS value,
        null,
        0
    FROM @calendar c
    LEFT OUTER JOIN events e ON (DatePart(q, c.date) = DatePart(q, e.eventDate) 
    AND e.eventType = 'CP' AND Year(eventDate) = @year)
    LEFT JOIN types t ON t.typeID = e.eventType
    GROUP BY e.employeeID, DatePart(q, c.date)

UPDATE @CarpoolTbl 
SET @earned = earned = Floor((@runningTotal + value)/20) - Floor(@runningTotal/20),
    @runningTotal = runningTotal = @runningTotal + value

FROM @CarpoolTbl

SELECT c.quarter, c.employeeID, a.DisplayName AS employee, c.value AS trips, earned *  30 AS earned
FROM @CarpoolTbl c
LEFT JOIN SBAIntranet.dbo.NTAuth a ON 'SBA\' + c.employeeID = a.AccountName
ORDER BY dateQ, employeeID

有什么想法吗?

编辑: 所有员工的运行总计出乎意料的结果,而不是员工:

Qtr   Employee  trips   tripsRunningTotal

Jan-Mar   Cathy     5.0     5.0
Apr-Jun   Cathy     3.0     375.5
Jul-Sep   Cathy     4.0     757.0
Jan-Mar   Carol     3.5     8.5
Apr-Jun   Carol     16.0    391.5
Jul-Sep   Carol     44.5    801.5

编辑2: 好的,这是我修改过的,更清晰,准确的版本。现在,找出赚来的美元部分。

-- carpool quarter stats
use TRPTracking

declare @employeeID NVarChar(100), @year Char(4)
Set     @year = '2014'
------
declare @startDate DateTime, @endDate DateTime
Set     @startDate = '1/1/' + @year
Set     @endDate = DateAdd(d,-1,DateAdd(yyyy,1,@startDate))


;WITH cte
     AS (SELECT Datepart(qq, e.eventDate) AS quarterNum,
     CASE DatePart(qq, e.eventDate) 
                WHEN 1 THEN 'Jan-Mar' 
                WHEN 2 THEN 'Apr-Jun' 
                WHEN 3 THEN 'Jul-Sep' 
                WHEN 4 THEN 'Oct-Dec' END AS quarter,
                e.employeeID,
                Sum(t.value) AS trips
         FROM   events e
         LEFT JOIN types t ON t.typeID = e.eventType
         WHERE e.eventType = 'CP' AND Year(eventDate) = @year
         GROUP  BY Datepart(quarter, eventDate), e.employeeID)
SELECT a.quarter, a.employeeID, nta.DisplayName AS employee, trips,  
           (SELECT Sum(trips)
            FROM   cte b
            WHERE  a.employeeID = b.employeeID
                   AND a.quarter >= b.quarter) as runningTotal
FROM   cte a 
LEFT JOIN SBAIntranet.dbo.NTAuth nta ON 'SBA\' + a.employeeID = nta.AccountName
ORDER BY a.employeeID, a.quarterNum

1 个答案:

答案 0 :(得分:0)

使用Correlated Subqueryrunning total分组后查找quarterInner Join是执行此操作的另一种选择

;WITH cte
     AS (SELECT Datepart(qq, dates) qq,
                employee,
                Sum(trips)          trips
         FROM   Yourtable
         GROUP  BY Datepart(qq, dates),
                   employee)
SELECT Employee,
       CASE qq
         WHEN 1 THEN 'Jan-Mar'
         WHEN 2 THEN 'Apr-Jun'
         WHEN 3 THEN 'Jul-Sep'
         WHEN 4 THEN 'Oct-Dec'
       END                       AS quarter,
       Trips,
       (SELECT Sum(trips)
        FROM   cte b
        WHERE  a.Employee = b.Employee
               AND a.qq >= b.qq) Running_Total
FROM   cte a 

SQLFIDDLE DEMO