SQL:在内部连接表上调整多行

时间:2012-03-23 01:40:14

标签: sql sql-server join conditional-statements

我需要一些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

我如何查询多个问题?

我正在寻找的是一套设置语法,可用于查询已回答任意数量问题的特定答案的不同成员列表,例如:

对喜欢((狗和红色)OR(猫和绿色))的成员的查询应返回:

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

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

感谢任何人都能给予的帮助,抱歉,如果它有点令人困惑。

2 个答案:

答案 0 :(得分:1)

您可以选择回答其中一个问题的个人ID,如下所示:

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

然后用内部联接替换ands,如下所示:

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

正如你所说,这就是“set sintax”:

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

如果您需要额外的条件,例如仅检查答案1和2,您可以使用具有常见条件的CTE,例如“(1,2)中的answerId”,以避免在每个选择中写入相同的条件,使得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等)的细节,以便更容易理解。

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