2

私は新しい Web 開発者で、ユーザーにクイズを提供する簡単なトレーニング管理システムを開発しています。ASP.NET と MS SQLServer を使用して開発されたシステム。ここで、提供されたすべての安全性クイズ (IsSent = true のクイズを意味します) における各部門の参加率を示すクエリを作成する必要があります。

次のデータベース設計があります。

Employee Table: Username,  Name,    DivisionCode
Divisions Table: SapCode, Divison
Quiz Table: QuizID, Title, Description, IsSent
UserQuiz: UserQuizID, QuizID, DateTimeComplete, Username

(DivisionCode は、SapCode への外部キーです。IsSent は、提供され、ユーザーに参加するように送信されたクイズに示すフラグです。)

たとえば、部門が 4 つあるとします。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

また、全体のパーセンテージは、各クイズの各部門のすべての達成率の合計です。たとえば、Quiz#1 の部門 A の完了率 = 40%、Quiz#2 = 60%、Quiz#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

それを改善し、必要なものを得るにはどうすればよいですか?

4

1 に答える 1

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
于 2012-08-14T13:48:36.277 に答える