2014-10-17 146 views
1

我正在尝试计算问卷系统的响应。我想在一个表格中显示结果(问题,选项,回复数量)。我写了一个可以正常工作的查询,但没有显示所有的选项,也没有显示任何响应。SQL表连接查询

我查询

SELECT  R.QuestionID, Q.QuestionName, A.OptionName, COUNT(R.OptionID) AS Responses, A.OptionID 
FROM   Response AS R 
INNER JOIN 
        Question AS Q ON Q.QuestionID = R.QuestionID 
INNER JOIN 
        Option AS A ON R.OptionID = A.OptionID 
WHERE  (R.QuestionnaireID = 122) 
GROUP BY R.QuestionID, Q.QuestionName, A.OptionName, R.OptionID, A.OptionID 

数据库结构

  • 问卷(questionnaireID PK,questionnaireName)
  • 问题(questionID PK,questionnaireID FK,questionnaireName)
  • 选项(OptionID PK,questionID FK,optionName)
  • 响应(ResponseID PK,questionnaireID FK,questionID FK,值)

表定义

CREATE TABLE [dbo].[Questionnaire] (
    [QuestionnaireID]   INT IDENTITY (1, 1) NOT NULL, 
    [QuestionnaireName]  NVARCHAR (100) NOT NULL, 
    PRIMARY KEY CLUSTERED ([QuestionnaireID] ASC), 
); 
CREATE TABLE [dbo].[Question] (
    [QuestionID]   INT IDENTITY (1, 1) NOT NULL, 
    [QuestionnaireID]  INT    NOT NULL, 
    [QuestionName]  NVARCHAR (250) NOT NULL, 
    PRIMARY KEY CLUSTERED ([QuestionID] ASC), 
    CONSTRAINT [FK_Question_Questionnaire] FOREIGN KEY ([QuestionnaireID]) REFERENCES [dbo].[Questionnaire] ([QuestionnaireID]) 
); 
CREATE TABLE [dbo].[Option] (
    [OptionID] INT    IDENTITY (1, 1) NOT NULL, 
    [QuestionID] INT    NOT NULL, 
    [OptionName] NVARCHAR (150) NOT NULL, 
    PRIMARY KEY CLUSTERED ([OptionID] ASC), 
    CONSTRAINT [FK_Option_Question] FOREIGN KEY ([QuestionID]) REFERENCES [dbo].[Question] ([QuestionID]) 
); 
CREATE TABLE [dbo].[Response] (
    [ResponseID]  INT    IDENTITY (1, 1) NOT NULL, 
    [QuestionnaireID] INT    NOT NULL, 
    [QuestionID]  INT    NOT NULL, 
    [Val]    NVARCHAR (150) NOT NULL, 
    [OptionID]  INT    NULL, 
    PRIMARY KEY CLUSTERED ([ResponseID] ASC), 
    CONSTRAINT [FK_Response_Option] FOREIGN KEY ([OptionID]) REFERENCES [dbo].[Option] ([OptionID]), 
    CONSTRAINT [FK_Response_Question] FOREIGN KEY ([QuestionID]) REFERENCES [dbo].[Question] ([QuestionID]), 
    CONSTRAINT [FK_Response_Questionnaire] FOREIGN KEY ([QuestionnaireID]) REFERENCES [dbo].[Questionnaire] ([QuestionnaireID]) 
); 

当前数据:

insert into questionnaire values ('ASP.NET questionnaire'); 
insert into questionnaire values('TEST questionnaire'); 

insert into question values (2, 'rate our services'); 
insert into question values (2, 'On scale from 1 to 5, how much youre sleepy?'); 
insert into question values (2, 'how are you today'); 

insert into [Option] values (1, 'good'); 
insert into [Option] values (1, 'bad'); 
insert into [Option] values (1, 'medium'); 

insert into [Option] values(2, '1'); 
insert into [Option] values(2, '2'); 
insert into [Option] values(2, '3'); 
insert into [Option] values(2, '4'); 
insert into [Option] values(2, '5'); 

insert into [option] values (3, 'fine'); 
insert into [option] values (3, 'great'); 
insert into [option] values (3, 'not bad'); 
insert into [option] values (3, 'bad'); 

insert into response values(2, 1, 'good', 1); 
insert into response values(2, 1, 'good', 1); 
insert into response values(2, 1, 'bad', 2); 
insert into response values(2, 1, 'good', 1); 

insert into response values(2, 2, '1', 4); 
insert into response values(2, 2, '3', 3); 
insert into response values(2, 2, '4', 5); 
insert into response values(2, 2, '5', 8); 

希望的输出

Output

SQL小提琴

Sql Fiddle

+1

你能分享一些样本数据和你试图达到的结果吗?我不确定我在追随。 – Mureinik 2014-10-17 14:31:03

+0

我已更新该问题。 – ElSS 2014-10-17 14:44:12

+0

请根据样本数据共享三个表格中的样本数据和所需的结果。 – Ram 2014-10-17 16:31:55

回答

1

您需要使用LEFT JOIN,如果你想display all the options and if there are no responses for them

编辑

我已经更新了基于你的SQL小提琴的答案。它在SQL Fiddle工作,并给你你想要的输出。

SELECT  Q.QuestionName AS Question, 
      A.OptionName AS [Option], 
      COUNT(R.OptionID) AS Responses 
FROM   Question AS Q 
INNER JOIN 
     [Option] AS A ON A.questionID = Q.questionID 
LEFT JOIN 
    Response AS R ON Q.QuestionID = R.QuestionID AND R.OptionId=A.Optionid 

WHERE  (Q.QuestionnaireID = 2) 
GROUP BY Q.QuestionID, Q.QuestionName, A.OptionName 
ORDER BY Q.QuestionName,A.OptionName 
+0

它返回与我的查询相同的结果。 – ElSS 2014-10-17 16:20:53

+0

你现在可以试试吗? – Ram 2014-10-17 19:20:32

+0

由于某种原因,它给出了值为1的零选项。我玩过它,但仍然......没有回应时它不显示空。 – ElSS 2014-10-17 20:37:11

0

试试这个:

select 
    R.QuestionID, isnull(Q.QuestionName, ''), isnull(A.OptionName, ''), 
    sum(case when A.OptionID is not null then 1 else 0 end) ResponsesCount 
from Response R 
left join Question Q on 
    R.QuestionID = Q.QuestionID 
left join [Option] A on 
    R.OptionID = A.OptionID 
where 
    R.QuestionnaireID = 122 
group by 
    R.QuestionID, isnull(Q.QuestionName, ''), 
    isnull(A.OptionName, ''), R.OptionID 

在这里,你看,我更换内连接至左连接考虑到没有回应选项。
此外,我改变了count逻辑 - 我们只需要计数非空ID(所以我在sum中使用case语句)。最后,我将所有'可能是空列'(从左连接的表格)包装到isnull函数中。

+0

它返回与我的查询相同的结果。 – ElSS 2014-10-17 16:22:18