我有以下查询,显示每个部门中最后一次发送测验的参与者数量。我希望保持原样但不是显示参与者的数量,而是要显示参与最后一次发送测验的百分比。
为了您的信息,我有以下数据库设计:
员工表: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]
答案 0 :(得分:1)
假设参与占总用户的百分比,请尝试:
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
答案 1 :(得分:0)
例如,参与者总数为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
答案 2 :(得分:0)
如果不是所有员工都参加了测验,那么我认为非参与者在UserQuiz表中没有条目。您需要对员工进行LEFT OUTER JOIN到userQuiz。通过这种方式,您可以获得所有员工,仅获得参与员工的测验结果。
然后从Employee获取所有DISTINCT员工姓名的计数 - 这是100%的员工,然后获得DISTINCT UserQuiz.Username的计数 - 并将其作为所有员工的百分比进行计算。这将为您提供参加测验的员工百分比