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

У меня есть следующий запрос, который показывает количество участников последней отправки теста в каждом подразделении.Я хочу оставить все как есть, но вместо того, чтобы показывать количество участников, я хочу показать процент участия в последней отправляющей викторине.

Для вашей информации, у меня есть следующий дизайн базы данных:

  • Сотрудник Таблица: Username, Name, Job, DivisionCode

  • Раздел таблица: SapCode, DivisionName

  • Викторина Таблица: QuizID, Title, Description, IsSent

  • UserQuiz таблица: UserQuizID, Score, DateTimeComplete, QuizID, Username

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

IsSent - это флагиспользуется для определения того, какой опрос отправляется пользователям, а какой нет.

Как изменить этот запрос, чтобы отображать процент участия?

Запрос SQL:

SELECT     
    dbo.Divisions.DivisionShortcut, 
    COUNT(DISTINCT dbo.UserQuiz.Username) AS [Number of Participants], 
    dbo.Quiz.QuizID
FROM
    dbo.Divisions 
INNER JOIN
    dbo.employee ON dbo.Divisions.SapCode = dbo.employee.DivisionCode 
INNER JOIN
    dbo.UserQuiz ON dbo.employee.Username = dbo.UserQuiz.Username 
INNER JOIN
    dbo.Quiz ON dbo.UserQuiz.QuizID = dbo.Quiz.QuizID
WHERE     
    [Quiz].[QuizID] = (SELECT MAX([QuizID]) FROM dbo.Quiz WHERE (IsSent = 1))
GROUP BY 
    dbo.Divisions.DivisionShortcut, dbo.Quiz.QuizID

Схема базы данных:

/****** Object:  Table [dbo].[Divisions]    Script Date: 03/07/2012 15:48:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Divisions](
    [SapCode] [float] NOT NULL,
    [DivisionShortcut] [varchar](10) NOT NULL,
    [DivisionName] [varchar](max) NOT NULL,
 CONSTRAINT [PK_Divisions] PRIMARY KEY CLUSTERED 
(
    [SapCode] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object:  Table [dbo].[Quiz]    Script Date: 03/07/2012 15:48:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Quiz](
    [QuizID] [int] IDENTITY(1,1) NOT NULL,
    [Title] [varchar](max) NOT NULL,
    [IsSent] [bit] NOT NULL,
    [Description] [varchar](max) NULL,
 CONSTRAINT [PK_Quiz] PRIMARY KEY CLUSTERED 
(
    [QuizID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object:  Table [dbo].[employee]    Script Date: 03/07/2012 15:48:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[employee](
    [Name] [nvarchar](max) NOT NULL,
    [Username] [nvarchar](255) NOT NULL,
    [JobTitle] [nvarchar](max) NOT NULL,
    [BadgeNo] [float] NOT NULL,
    [EmpOrgType] [float] NOT NULL,
    [DivisionCode] [float] NOT NULL,
 CONSTRAINT [PK_employee] PRIMARY KEY CLUSTERED 
(
    [Username] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[UserQuiz]    Script Date: 03/07/2012 15:48:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserQuiz](
    [UserQuizID] [int] IDENTITY(1,1) NOT NULL,
    [QuizID] [int] NOT NULL,
    [DateTimeComplete] [smalldatetime] NOT NULL,
    [Score] [float] NOT NULL,
    [Username] [nvarchar](255) NOT NULL,
 CONSTRAINT [PK_UserQuiz] PRIMARY KEY CLUSTERED 
(
    [UserQuizID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Default [DF_Quiz_IsSent]    Script Date: 03/07/2012 15:48:13 ******/
ALTER TABLE [dbo].[Quiz] ADD  CONSTRAINT [DF_Quiz_IsSent]  DEFAULT ((0)) FOR [IsSent]
GO
/****** Object:  ForeignKey [FK_employee_Divisions]    Script Date: 03/07/2012 15:48:13 ******/
ALTER TABLE [dbo].[employee]  WITH CHECK ADD  CONSTRAINT [FK_employee_Divisions] FOREIGN KEY([DivisionCode])
REFERENCES [dbo].[Divisions] ([SapCode])
GO
ALTER TABLE [dbo].[employee] CHECK CONSTRAINT [FK_employee_Divisions]
GO
/****** Object:  ForeignKey [FK_UserQuiz_employee]    Script Date: 03/07/2012 15:48:13 ******/
ALTER TABLE [dbo].[UserQuiz]  WITH CHECK ADD  CONSTRAINT [FK_UserQuiz_employee] FOREIGN KEY([Username])
REFERENCES [dbo].[employee] ([Username])
GO
ALTER TABLE [dbo].[UserQuiz] CHECK CONSTRAINT [FK_UserQuiz_employee]
GO
/****** Object:  ForeignKey [FK_UserQuiz_Quiz]    Script Date: 03/07/2012 15:48:13 ******/
ALTER TABLE [dbo].[UserQuiz]  WITH CHECK ADD  CONSTRAINT [FK_UserQuiz_Quiz] FOREIGN KEY([QuizID])
REFERENCES [dbo].[Quiz] ([QuizID])
GO
ALTER TABLE [dbo].[UserQuiz] CHECK CONSTRAINT [FK_UserQuiz_Quiz]

Ответы [ 3 ]

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

Принимая участие в процентах от общего числа пользователей, попробуйте:

SELECT     dbo.Divisions.DivisionShortcut, 
           COUNT(DISTINCT dbo.UserQuiz.Username) AS [Number of Participants], 
           COUNT(DISTINCT dbo.UserQuiz.Username) * 100 
                   / MAX([AllUsers].[UserCount]) AS [Percent Participation], 
           dbo.Quiz.QuizID
FROM       (SELECT COUNT(*) [UserCount] from dbo.employee) as [AllUsers]
CROSS JOIN dbo.Divisions 
INNER JOIN dbo.employee 
        ON dbo.Divisions.SapCode = dbo.employee.DivisionCode 
INNER JOIN dbo.UserQuiz
        ON dbo.employee.Username = dbo.UserQuiz.Username 
INNER JOIN dbo.Quiz
        ON dbo.UserQuiz.QuizID = dbo.Quiz.QuizID
WHERE   [Quiz].[QuizID] = (SELECT MAX([QuizID]) FROM dbo.Quiz WHERE (IsSent = 1))
GROUP BY dbo.Divisions.DivisionShortcut, dbo.Quiz.QuizID

РЕДАКТИРОВАТЬ: Предоставляя пользователям возможность отвечать на вопросы более одного раза, вы сможете выполнить следующий запрос, чтобы вернуть процент участия пользователей на уровне отдела:

SELECT     DivisionShortcut, 
           MAX(NumberParticipants) - MAX(NullParticipant) AS [Number of Participants], 
           (MAX(NumberParticipants) - MAX(NullParticipant)) * 100 
                  / MAX(DivisionEmployees) AS [Percent Participation], 
           MAX(LatestQuiz) AS LatestQuiz
FROM
(SELECT     D.DivisionShortcut, 
            DENSE_RANK() OVER (PARTITION BY D.DivisionShortcut ORDER BY UQ.Username) 
                  AS NumberParticipants,
            CASE WHEN UQ.Username IS NULL THEN 1 ELSE 0 END AS NullParticipant,
            DENSE_RANK() OVER (PARTITION BY D.DivisionShortcut ORDER BY E.Username) 
                  AS DivisionEmployees,
            LQ.LatestQuiz
 FROM       (SELECT MAX([QuizID]) AS LatestQuiz FROM dbo.Quiz WHERE (IsSent = 1)) AS LQ
 CROSS JOIN dbo.Divisions AS D
 INNER JOIN dbo.employee AS E
         ON D.SapCode = E.DivisionCode 
 LEFT JOIN  dbo.UserQuiz AS UQ
         ON E.Username = UQ.Username AND LQ.LatestQuiz = UQ.QuizID) AS SQ
GROUP BY DivisionShortcut
0 голосов
/ 07 марта 2012

Если не все сотрудники участвуют в опросе, то я предполагаю, что неучастники не имеют записи в таблице UserQuiz. Вам понадобится ЛЕВОЕ НАРУЖНОЕ СОЕДИНЕНИЕ от сотрудника к userQuiz. Таким образом, вы получите всех сотрудников и только результаты теста для участвующих сотрудников.

Затем получите количество всех имен сотрудников DISTINCT от Employee (это 100% сотрудников), затем получите значение Count из DISTINCT UserQuiz.Username - и рассчитайте его как процент от всех сотрудников. Это даст вам процент сотрудников, участвующих в викторине

0 голосов
/ 07 марта 2012

Например, общее количество участников 50, тогда ваш запрос должен быть таким:

SELECT     dbo.Divisions.DivisionShortcut, (COUNT(DISTINCT dbo.UserQuiz.Username)/50)*100 AS [Percentage of Participarion], dbo.Quiz.QuizID
FROM         dbo.Divisions INNER JOIN
                      dbo.employee ON dbo.Divisions.SapCode = dbo.employee.DivisionCode INNER JOIN
                      dbo.UserQuiz ON dbo.employee.Username = dbo.UserQuiz.Username INNER JOIN
                      dbo.Quiz ON dbo.UserQuiz.QuizID = dbo.Quiz.QuizID
WHERE     [Quiz].[QuizID] = (SELECT MAX([QuizID]) FROM dbo.Quiz WHERE (IsSent = 1))
GROUP BY dbo.Divisions.DivisionShortcut, dbo.Quiz.QuizID
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...