Как найти общее количество сотрудников в каждом подразделении, чтобы показать процент выполнения в каждом подразделении с помощью этого SQL-запроса? - PullRequest
0 голосов
/ 04 марта 2012

Я занимаюсь разработкой веб-приложения для своей компании. Это приложение предоставляет пользователям викторины. Теперь мне нужно разработать мощную и значимую панель управления для руководства. На панели инструментов должно отображаться% участия = (сумма всех опросов, проведенных каждым сотрудником) / (общее количество сотрудников * общее количество опросов)

Вопрос: у меня следующий дизайн базы данных:

Таблица сотрудников: Имя пользователя, Имя, Работа, DivisionID

Таблица подразделений: DivisionID, DivisionName

Таблица тестов: QuizID, Название, Описание

Таблица UserQuiz: UserQuizID, Score, DateTimeComplete, QuizID, Имя пользователя

ПРИМЕЧАНИЕ. Первым атрибутом в каждой таблице является первичный ключ.

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 Ответ

1 голос
/ 04 марта 2012

Попробуйте это:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...