我需要一些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
可能有任何答案组合。它的本质是如何查询内部连接表的多个值?
感谢任何人都能给予的帮助,抱歉,如果它有点令人困惑。
答案 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');