我是一名新的网络开发人员,我正在开发一个简单的培训管理系统,为用户提供测验。该系统使用ASP.NET和MS SQLServer开发。现在, 我需要提出一个查询,显示每个部门在所有提供的安全测验中的参与百分比(这意味着IsSent的测验为真)。
我有以下数据库设计:
Employee Table: Username, Name, DivisionCode
Divisions Table: SapCode, Divison
Quiz Table: QuizID, Title, Description, IsSent
UserQuiz: UserQuizID, QuizID, DateTimeComplete, Username
(DivisionCode是SapCode的外键.IsSent是一个标志,用于指示已提供并发送给用户参与其中的测验。)
例如,如果我有四个部门; A,B,C和D,我已经向这些部门的员工发送了大约23个测验。由于每个部门在每个测验中都有特定的参与百分比。我的查询应显示每个部门参与所有提供的测验的总体百分比。所以结果不应该针对每个测验进行细分。
那怎么做?
这是数据库的模式及其数据:
USE [Test]
GO
/****** Object: Table [dbo].[Divisions] Script Date: 08/03/2012 19:36:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Divisions](
[SapCode] [nvarchar](50) NOT NULL,
[Division] [varchar](50) 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
INSERT [dbo].[Divisions] ([SapCode], [Division]) VALUES (N'1', N'A')
INSERT [dbo].[Divisions] ([SapCode], [Division]) VALUES (N'2', N'B')
INSERT [dbo].[Divisions] ([SapCode], [Division]) VALUES (N'3', N'C')
/****** Object: Table [dbo].[Quiz] Script Date: 08/03/2012 19:36:09 ******/
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](50) NOT NULL,
[Description] [varchar](50) NOT NULL,
[IsSent] [bit] NOT 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
SET IDENTITY_INSERT [dbo].[Quiz] ON
INSERT [dbo].[Quiz] ([QuizID], [Title], [Description], [IsSent]) VALUES (1, N'Quiz I', N'Test', 1)
INSERT [dbo].[Quiz] ([QuizID], [Title], [Description], [IsSent]) VALUES (2, N'Quiz II', N'Test test', 1)
INSERT [dbo].[Quiz] ([QuizID], [Title], [Description], [IsSent]) VALUES (3, N'Quiz III', N'TEST TEST', 0)
SET IDENTITY_INSERT [dbo].[Quiz] OFF
/****** Object: Table [dbo].[Employee] Script Date: 08/03/2012 19:36:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Employee](
[Usename] [nvarchar](50) NOT NULL,
[Name] [varchar](50) NOT NULL,
[DivisionCode] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
(
[Usename] 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
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'John12', N'John A', N'1')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'John13', N'John B', N'1')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'John15', N'John C', N'3')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Maria12', N'Maria A', N'3')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Rony14', N'Rony A', N'2')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Tid52', N'Tid A', N'3')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Tim12', N'Tim A', N'1')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Tim15', N'Tim B', N'2')
/****** Object: Table [dbo].[UserQuiz] Script Date: 08/03/2012 19:36:09 ******/
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] [datetime] NOT NULL,
[Score] [float] NOT NULL,
[Username] [nvarchar](50) 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
SET IDENTITY_INSERT [dbo].[UserQuiz] ON
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (1, 1, CAST(0x0000A07900000000 AS DateTime), 100, N'John12')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (2, 1, CAST(0x0000A07900000000 AS DateTime), 50, N'Tim12')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (3, 1, CAST(0x0000A07B00000000 AS DateTime), 100, N'Rony14')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (4, 1, CAST(0x0000A07900000000 AS DateTime), 0, N'Tim15')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (5, 1, CAST(0x0000A07900000000 AS DateTime), 100, N'Tid52')
SET IDENTITY_INSERT [dbo].[UserQuiz] OFF
/****** Object: ForeignKey [FK_Employee_Divisions] Script Date: 08/03/2012 19:36:09 ******/
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: 08/03/2012 19:36:09 ******/
ALTER TABLE [dbo].[UserQuiz] WITH CHECK ADD CONSTRAINT [FK_UserQuiz_Employee] FOREIGN KEY([Username])
REFERENCES [dbo].[Employee] ([Usename])
GO
ALTER TABLE [dbo].[UserQuiz] CHECK CONSTRAINT [FK_UserQuiz_Employee]
GO
/****** Object: ForeignKey [FK_UserQuiz_Quiz] Script Date: 08/03/2012 19:36:09 ******/
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]
GO
更新 结果应该是这样的:
分部 * ** * ** * ** * *** 总体百分比
* ** * ** * ** * ** * ** * 80
B * ** * ** * ** * ** * ** * 60
C * ** * ** * ** * ** * ** * 50
总体百分比是每个测验中每个分部完成百分比的总和。例如,测验#1中A组的完成百分比= 40%,测验#2 = 60%,测验#3 = 90%,此查询应显示的总百分比是所有的总和它们除以发送的测验总数(即3)。我希望我很清楚,这个概念很明显。
更新#2:
我仍在努力解决这个问题,但我想出了一个查询,显示每个部门每个测验的员工和参与者总数。这是查询:
SELECT COUNT(dbo.Employee.Usename) AS [Total Number of Employees], COUNT(dbo.UserQuiz.Username) AS [Total Number of Participants], dbo.Divisions.Division,
dbo.Quiz.Title
FROM dbo.Divisions INNER JOIN
dbo.Employee ON dbo.Divisions.SapCode = dbo.Employee.DivisionCode INNER JOIN
dbo.UserQuiz ON dbo.Employee.Usename = dbo.UserQuiz.Username INNER JOIN
dbo.Quiz ON dbo.UserQuiz.QuizID = dbo.Quiz.QuizID
WHERE (dbo.Quiz.IsSent = 1)
GROUP BY dbo.Divisions.Division, dbo.Quiz.Title
我应该怎样做才能改善它并获得我需要的东西?
答案 0 :(得分:0)
以下查询可能会执行您想要的操作。我计算每个部门的员工人数,并将其乘以测验数量。然后它除以这个总数实际采用的数字:
select de.Division, de.numemployees, de.numemployees*q.numquizzes as qe_combos,
numquizzestaken/1.0*de.numemployees*q.numquizzes as proportion
from (select d.Division, count(*) as numemployees
from Employee e join
Division d
on e.DivisionCode = d.SapCode
group by d.Division
) de left outer join
(select d.Division, count(*) as numquizzestaken
from Employee e join
Division d
on e.DivisionCode = d.SapCode join
UserQuiz uq
on e.UserName = uq.UserName join
Quiz q
on uq.QuidId = q.QuizId and
q.issent = true
group by de.Division
) dq
on de.division = dq.division cross join
(select count(*) as numquizes
from Quiz q
where isSent = true
) q