如何使用此SQL查询查找每个部门中的员工总数以显示每个部门的完成百分比?

时间:2012-03-04 05:12:23

标签: sql sql-server-2008-r2

我正在为我的公司开发一个Web应用程序。此应用程序为用户提供测验。现在,我需要为管理层开发一个功能强大且有意义的仪表板。仪表板必须显示show%participation =(每位员工所有测验的总和)/(员工总数*测验总数)

问题是:我有以下数据库设计:

员工表:用户名,姓名,职位,分部ID

分区表:DivisionID,DivisionName

测验表:QuizID,标题,描述

UserQuiz表:UserQuizID,Score,DateTimeComplete,QuizID,Username

注意:每个表中的第一个属性是主键。

我正在使用的SQL查询(但我不确定)显示完成百分比是:

DECLARE @LastDayOfPrevMonth DATETIME, @FirstDayOfThreeMonthsBefore DATETIME

SET @FirstDayOfThreeMonthsBefore = DATEADD(MONTH, -2, DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0))
SET @LastDayOfPrevMonth = GETDATE()

;WITH MonthCTE AS
(
SELECT DATENAME(MONTH, DATEADD(MONTH, -2, CURRENT_TIMESTAMP)) + '-' + DATENAME(YEAR, DATEADD(MONTH, -2, CURRENT_TIMESTAMP)) AS MonthYear
UNION ALL 
SELECT DATENAME(MONTH, DATEADD(MONTH, -1, CURRENT_TIMESTAMP)) + '-' + DATENAME(YEAR, DATEADD(MONTH, -1, CURRENT_TIMESTAMP))
UNION ALL
SELECT DATENAME(MONTH, DATEADD(MONTH, 0, CURRENT_TIMESTAMP)) + '-' + DATENAME(YEAR, DATEADD(MONTH, 0, CURRENT_TIMESTAMP))
)

    SELECT  Divisions.DivisionName
,       [Percentage Participation] = CAST([Total Number of Quizzes Taken]
        * 100.00 / [Total Number of Quizzes] AS DECIMAL(18, 2))
,       [Total Number of Quizzes Taken]
,       [Total Number of Quizzes]
,     [Total Number of Employees]
,       MonthYear [Month]
,     LEFT([MonthYear],3) + RIGHT([MonthYear], LEN([MonthYear]) - CHARINDEX('-',[MonthYear]) + 1) FirstThreeLettersOfMonth

FROM    dbo.Divisions Divisions CROSS JOIN 
    (SELECT ISNULL(NULLIF(COUNT(*),0),1) [Total Number of Quizzes]FROM [dbo].[Quiz] ) Quiz
    OUTER APPLY (SELECT COUNT(*) AS [Total Number of Employees] 
               FROM [dbo].[employee]
               WHERE employee.DivisionCode = Divisions.SapCode
               ) Employee 
    OUTER APPLY (
                 SELECT    ISNULL([Total Number of Quizzes Taken],0) [Total Number of Quizzes Taken],
                           MonthCTE.MonthYear FROM
                 (SELECT   COUNT(DISTINCT UserQuiz.QuizID) AS [Total Number of Quizzes Taken],
                            DATENAME(MONTH, UserQuiz.DateTimeComplete) + '-' + DATENAME(YEAR, UserQuiz.DateTimeComplete) MonthYear
                  FROM      UserQuiz UserQuiz
                            INNER JOIN employee employee 
                            ON UserQuiz.Username = employee.Username
                  WHERE     employee.DivisionCode = Divisions.SapCode 
                  AND       UserQuiz.DateTimeComplete BETWEEN @FirstDayOfThreeMonthsBefore AND @LastDayOfPrevMonth
                  GROUP BY DATENAME(MONTH, UserQuiz.DateTimeComplete), DATENAME(YEAR, UserQuiz.DateTimeComplete)
                  )Quiz
                  RIGHT JOIN MonthCTE ON Quiz.MonthYear = MonthCTE.MonthYear
                ) QuizMonthOutput

我现在想要的只是显示上一个月的完成百分比。

我认为我现在的问题只是找到每个部门的员工总数,将其添加到上述查询的这一部分:

SELECT  Divisions.DivisionShortcut
,       [Percent Completion] = CAST([Sum of all Quizzes Taken by each Employee]
        * 100.00 / ([Total Number of Employees]*[Total Number of Quizzes]) AS DECIMAL(18, 2))

那怎么做?

所需输出的示例:

计算应该是:完成百分比应如上所述计算,等于(每位员工所有测验的总和)/(员工总数*测验总数) 。例如,在A部门,如果有两名员工Emp1和Emp2。每个月,有四个测验。 Emp1参加了测验#1和测验#2,Emp2参加了测验#4。完成百分比应为=((Emp1 * 2测验)+(Emp2 * 1测验))/(员工总数*测验总数)

完成百分比=(2 + 1)/(2 * 4)= 2/8 = 0.25

1 个答案:

答案 0 :(得分:1)

试试这个:

DROP TABLE #Employee
DROP TABLE #Division
DROP TABLE #Quiz
DROP TABLE #UserQuiz

CREATE TABLE #Employee(
  Username  CHAR(10), 
  Name  VARCHAR(20),
  Job       VARCHAR(20),
  DivisionID    INT
)
INSERT INTO #Employee(Username, Name, Job, DivisionID) VALUES
('Me', 'Me', 'job1', 1),
('Myself', 'Myself', 'job2', 1),
('Andy', 'Andy', 'job3', 1),
('Ai', 'Ai', 'job4', 2)

CREATE TABLE #Division(
  DivisionID    INT, 
  DivisionName  VARCHAR(20)
)
INSERT INTO #Division(DivisionID, DivisionName) VALUES
(1, 'Div1'),
(2, 'Div2')

CREATE TABLE #Quiz(
  QuizID    INT, 
  Title VARCHAR(20), 
  Description   VARCHAR(20)
)
INSERT INTO #Quiz(QuizID, Title, Description) VALUES
(1, 'Quiz1', 'Quiz1'),
(2, 'Quiz2', 'Quiz2'),
(3, 'Quiz3', 'Quiz3'),
(4, 'Quiz4', 'Quiz4'),
(5, 'Quiz5', 'Quiz5'),
(6, 'Quiz6', 'Quiz6'),
(7, 'Quiz7', 'Quiz7'),
(8, 'Quiz8', 'Quiz8')

CREATE TABLE #UserQuiz(
  UserQuizID    INT, 
  Score INT, 
  DateTimeComplete  DATETIME, 
  QuizID    INT, 
  Username  CHAR(10), 
)
INSERT INTO #UserQuiz(UserQuizID, Score, DateTimeComplete, QuizID, Username) VALUES
(1, 10, '20000101', 1, 'Me'),
(2, 0,  '20000101', 1, 'Myself'),
(3, 10, '20120210', 5, 'Me'),
(4, 10, '20120210', 6, 'Myself'),
(5, 10, '20120210', 7, 'Andy'),
(6, 10, '20120101', 5, 'Ai')

DECLARE @LastDayOfPrevMonth DATETIME, @FirstDayOfPrevMonth DATETIME

SET @FirstDayOfPrevMonth = DATEADD(dd, -DAY(DATEADD(mm, 1, GetDate()) - 1), DATEADD(mm, -1, GetDate()))
SET @LastDayOfPrevMonth = DATEADD(dd, -DAY(DATEADD(m, 1, GetDate())), DATEADD(m, 0, GetDate()))

;WITH LastMontQuizes AS
(SELECT distinct QuizID
FROM #UserQuiz
WHERE DateTimeComplete BETWEEN @FirstDayOfPrevMonth AND @LastDayOfPrevMonth
),
NumberOfQuizes AS
(SELECT COUNT(*) as NumberOfQuizes
FROM LastMontQuizes
),
NrOfQuizesPerDivision AS
(SELECT COUNT(*) as NrOfQuizesPerDivision, #Division.DivisionID
FROM #Division
  INNER JOIN #Employee ON
    #Division.DivisionID = #Employee.DivisionID
  INNER JOIN #UserQuiz ON
    #Employee.Username = #UserQuiz.Username
  INNER JOIN LastMontQuizes ON
    #UserQuiz.QuizID = LastMontQuizes.QuizID
GROUP BY #Division.DivisionID
),
NrOfEmployeesPerDivision AS
(SELECT COUNT(*) as NrOfEmployeesPerDivision, #Division.DivisionID
FROM #Division
  INNER JOIN #Employee ON
    #Division.DivisionID = #Employee.DivisionID
GROUP BY #Division.DivisionID
)
SELECT #Division.DivisionName,
  NrOfQuizesPerDivision.DivisionID, 
  NrOfQuizesPerDivision.NrOfQuizesPerDivision * 100.0 / (NrOfEmployeesPerDivision.NrOfEmployeesPerDivision + NumberOfQuizes.NumberOfQuizes) AS Percentage,
  NrOfQuizesPerDivision.NrOfQuizesPerDivision,
  NrOfEmployeesPerDivision.NrOfEmployeesPerDivision,
  NumberOfQuizes.NumberOfQuizes
FROM NrOfQuizesPerDivision
  INNER JOIN NrOfEmployeesPerDivision ON
    NrOfQuizesPerDivision.DivisionID = NrOfEmployeesPerDivision.DivisionID
  INNER JOIN #Division ON
    NrOfQuizesPerDivision.DivisionID = #Division.DivisionID
  CROSS JOIN NumberOfQuizes