2012-03-23 31 views
1

我需要一些SQL语法的帮助。SQL:调整内部连接表上的多行

说我有一个会员表,问表和答案表,是表的基本如下:

成员表:

memberId: primary key 

问题表:

questionId: primary key, 
questionText:varchar 

答案表:

answerId: primary key, 
questionId: int (relating to the row of the question in the questions table) 
memberId: int (relating to the row of the member in the members table) 
answerValue:varchar 

这些表格将有更多的列,但为了这个问题的目的,这些应该就足够了。

现在在某些情况下,我想要运行一个查询,该查询将返回成员id不同的列表,其中成员回答的问题列表与特定值匹配。

例如:

说存在问题表中的问题与问题文本(行1):“你喜欢猫还是狗?”:

questionId    questionText 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
     1     Do you like cats or dogs? 

再就是10成员成员表从ID 1到10,并在答案表中对应的答案:

answerid    questionId    memberId    answerId 
--------------------------------------------------------------------------------------- 
1      1      1      cats 
2      1      2      both 
3      1      3      cats 
4      1      4      cats 
5      1      5      cats 
6      1      6      dogs 
7      1      7      dogs 
8      1      8      dogs 
9      1      9      dogs 
10      1      10     both 

这将是足够简单,这个例如查询,那些谁回答狗:

SELECT DISTINCT memberId FROM members INNER JOIN answers ON members.memberId = answers.answerId WHERE answers.questionId = 1 AND answers.answerValue = 'dogs' 

这将返回:

memberId 
--------------- 
     6 
     7 
     8 
     9 

但是如果我是另一个问题添加到问题表:

questionId    questionText 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
     1     Do you like cats or dogs? 
     2     What is your favourite color? 

答案和表进行了更新如下:

answerid    questionId    memberId    answerId 
--------------------------------------------------------------------------------------- 
1      1      1      cats 
2      1      2      both 
3      1      3      cats 
4      1      4      cats 
5      1      5      cats 
6      1      6      dogs 
7      1      7      dogs 
8      1      8      dogs 
9      1      9      dogs 
10      1      10     both 
11      2      1      blue 
12      2      2      red 
13      2      3      green 
14      2      5      green 
15      2      4      black 
16      2      6      violet 
17      2      7      pink 
18      2      8      green 
19      2      9      red 
20      2      10     yellow 

我如何查询多多疑问?

我所寻找的是一个集合的语法,将工作进行查询谁回答具体的答案,任何数量的问题,不同的成员列表,例如:

查询谁喜欢成员((狗和红色)或(猫和绿色))应返回:

memberId 
----------------- 
     9 
     3 
     5 

可能有任何答案的组合。它的本质是如何查询内联表的多个值?

感谢任何人可以给予的帮助,如果它有点混淆,对不起。

+0

它很难解释真实世界的这种实现,但我已经尝试了基本上我已经设计了一个电子邮件引擎,它需要一个条件列表(动物=猫和颜色=绿色(当然非常简化))并通过生成一个sql查询来查询数据库中是否符合这些条件的成员,然后发送电子邮件到返回的id。 – Neaox 2012-03-23 01:50:52

+0

根据给出的例子,我试过SELECT DISTINCT memberId FROM members INNER JOIN答案ON members.memberId = answers.answerId WHERE(((answers.questionId = 1 AND answers.answerValue ='dogs')AND(answers.questionId = 2 AND answers.answerValue ='red'))OR((answers.questionId = 1 AND answers.answerValue ='cats')AND(answers.questionId = 2 AND answers.answerValue ='green'))) – Neaox 2012-03-23 01:51:30

+0

我无法分辨你在这里问什么。您在上述评论中的连接查询甚至没有意义。你为什么要加入memberid = answerid? – kenny 2012-03-23 02:28:01

回答

1

您可以选择谁回答的一个问题,像这样的个人标识:

select distinct memberId where answerId = 'dogs' 
select distinct memberId where answerId = 'red' 

,然后更换阿富汗国家发展战略与内部连接,像这样:

select memberId from 
(select distinct memberId where answerId = 'dogs') D 
inner join 
(select distinct memberId where answerId = 'red') R 
on D.MemberId = R.memberId 

而更换与UNION的OR,如下所示:

select memberId from 
(select distinct memberId where answerId = 'dogs') D 
inner join 
(select distinct memberId where answerId = 'red') R 
on D.MemberId = R.memberId 
union 
select memberId from 
(select distinct memberId where answerId = 'cats') D 
inner join 
(select distinct memberId where answerId = 'green') R 
on D.MemberId = R.memberId 

这正是像你说的,一个“设置sintax”:

Set: each indivdual select 
Intersection of sets : inner join 
Union of sets: union 

如果你需要额外的条件,例如只检查答案1和2,你可以使用一个CTE中包含“answerId共同条件在(1,2)中“,以避免在每个选择中写入相同的条件,使得sintax更清晰。

您也可以使用此sintax,这更类似于原来的文字:

select memberId from members M 
where 
(exists (select 1 from answers where answerId='dogs' and memberId=M.member Id) 
    and exists (select 1 from answers where answerId='red' and memberId=M.member Id)) 
    or 
(exists (select 1 from answers where answerId='cats' and memberId=M.member Id) 
    and exists (select 1 from answers where answerId='green' and memberId=M.member Id)) 
-- I select 1 instead of * or any column for performance reasons 

我离开了增加额外的检查(answerId等),使之更容易理解的细节。

+0

感谢你们,以及我将在本周末做很多代码重写:((我的SQL查询一代。) – Neaox 2012-03-23 02:10:23

-2
SELECT DISTINCT memberId 
FROM members 
WHERE answers.questionId=1 AND answers.answerValue IN ('dogs','red') 
UNION 
SELECT DISTINCT memberId 
FROM members 
WHERE answers.questionId=2 AND answers.answerValue IN ('cats,'green'); 
+0

行如何满足这样的条件:(answers.answerValue ='狗'AND answers.answerValue ='红')? – JotaBe 2012-03-23 01:52:59

+0

除了我的第一条评论,你不需要链接成员表。您可以从答案表中获取memberId。为什么加入会员表?想想你的问题! – JotaBe 2012-03-23 02:01:22

+0

你是对的JotaBe。 – Teja 2012-03-23 02:05:46