SQL表加入查询

时间:2014-10-17 14:29:09

标签: 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

数据库结构

  • 问卷调查(问卷调查ID PK,问卷名称)
  • 问题(questionID PK,问卷ID FK,问卷名称)
  • 选项(OptionID PK,questionID FK,optionName)
  • 响应(ResponseID PK,问卷ID 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

3 个答案:

答案 0 :(得分:3)

这可能与你的内连接有关。内部联接仅生成在表A和表B中匹配的记录集。

审核此信息可能会有所帮助http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/

答案 1 :(得分: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

答案 2 :(得分: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(所以我在case中使用sum语句)。最后,我把所有可能都是空列的' (从左边连接的表格)到isnull func。