开发市场调查业务,有一个调查问题表responses (一百万行), 是市场调查的原始数据,包含survey_id(调查表的类型列),response_no(被调查者列),interview_date(调查日期), question_label(问题列), value(回答列), section_unique_id(部门列)等。
每一行对应某个被调查者回答的一个问题和它的调查结果。一个被调查者一次会回答30个问题,所以会产生30行。
另有一个计算公式表 (40行), 是对调查结果的分析计算公式,这些公式都是sql语句。
根据计算公式,产生一个结果表results。
现在的问题是,要设计一些sql语句,调查有多少人的回答是类似如下这样的组合:
1. 回答问题Q1,答案是1或8或9
并且
2. 回答问题Q2,答案是1或8或9
并且
。。。。。。
最好能用group by section。
比如如下这个例子:
计算公式的说明是这样。
((Q2A = 1 OR Q2A = 8 OR Q2A = 9) AND (Q2B = 1 OR Q2B = 8 OR Q2B = 9) AND (Q2C = 1 OR Q2C = 8 OR Q2C = 9) AND (Q2D = 1 OR Q2D = 8 OR Q2D = 9) AND (Q2E = 1 OR Q2E = 8 OR Q2E = 9) AND (Q2F = 1 OR Q2F = 8 OR Q2F = 9) AND (Q2G = 1 OR Q2G = 8 OR Q2G = 9) AND (Q2H = 1 OR Q2H = 8 OR Q2H = 9) AND (Q2I = 1 OR Q2I = 8 OR Q2I = 9) AND (Q5 = 1 OR Q5 = 8 OR Q5 = 9) AND (Q6 = 1 OR Q6 = 8 OR Q6 = 9))
我现在写了这样一个mysql语句:
SELECT section_unique_id as "section_unique_id", COUNT(*) as "hit" FROM responses WHERE
question_label = "Q2A" AND value IN (1,8,9)
AND
(response_no, survey_id, interview_date) IN (SELECT DISTINCT response_no, survey_id, interview_date FROM responses WHERE question_label = "Q2B" AND value IN (1,8,9))
AND
(response_no, survey_id, interview_date) IN (SELECT DISTINCT response_no, survey_id, interview_date FROM responses WHERE question_label = "Q2C" AND value IN (1,8,9))
AND
(response_no, survey_id, interview_date) IN (SELECT DISTINCT response_no, survey_id, interview_date FROM responses WHERE question_label = "Q2D" AND value IN (1,8,9))
AND
(response_no, survey_id, interview_date) IN (SELECT DISTINCT response_no, survey_id, interview_date FROM responses WHERE question_label = "Q2E" AND value IN (1,8,9))
AND
(response_no, survey_id, interview_date) IN (SELECT DISTINCT response_no, survey_id, interview_date FROM responses WHERE question_label = "Q2F" AND value IN (1,8,9))
AND
(response_no, survey_id, interview_date) IN (SELECT DISTINCT response_no, survey_id, interview_date FROM responses WHERE question_label = "Q2G" AND value IN (1,8,9))
AND
(response_no, survey_id, interview_date) IN (SELECT DISTINCT response_no, survey_id, interview_date FROM responses WHERE question_label = "Q2H" AND value IN (1,8,9))
AND
(response_no, survey_id, interview_date) IN (SELECT DISTINCT response_no, survey_id, interview_date FROM responses WHERE question_label = "Q2I" AND value IN (1,8,9))
AND
(response_no, survey_id, interview_date) IN (SELECT DISTINCT response_no, survey_id, interview_date FROM responses WHERE question_label = "Q5" AND value IN (1,8,9))
AND
(response_no, survey_id, interview_date) IN (SELECT DISTINCT response_no, survey_id, interview_date FROM responses WHERE question_label = "Q6" AND value IN (1,8,9))
结果,运行一次,用了12秒,太慢了。
请教mysql高手,有没有办法能加快计算速度。
1
cye3s 2014-12-10 11:37:46 +08:00 via Android
那么多子查询,快就怪了,先用sum(case...l
)语句转横表,就是每人一行记录,包含所有问题回答,试试 |
2
xiyangyang OP 对mysql不熟悉,但是要求比较急,可否请大侠写这个sql语句?谢谢了。
|
3
airylinus 2014-12-10 13:04:25 +08:00
最简单的加速方法是用视图,怎么用查 MySQL 文档。
另外,还可以把每个问题的答案转换成二进制,用二进制运算替代子查询。 |
4
tranch 2014-12-10 13:14:44 +08:00
SELECT section_unique_id AS "section_unique_id",
COUNT(*) AS "hit" FROM responses WHERE (response_no, survey_id, interview_date) IN (SELECT DISTINCT response_no, survey_id, interview_date FROM responses WHERE question_label IN ("Q2A", "Q2B", "Q2C", "Q2B", "Q2D", "Q2E", "Q2F", "Q2G", "Q2H", "Q2I", "Q5", "Q6") AND value IN (1, 8, 9)) |
5
xiyangyang OP tranch:
我们想要的是,知道有多少个这样的被调查者,他回答的问题满足这样的条件:Q2A in (1,8,9) 并且Q2B in (1,8,9), ..... 所以,question_label IN ("Q2A", "Q2B", 。。。。。。), 这样是不对的 airylinus: 每个问题的答案都是1到10的整数,没法转换成二进制,因为其他的计算公式还需要他们呢。 |
6
tranch 2014-12-10 13:43:33 +08:00
建议把以上问题贴到问答网站(比如 segmentfault.com)上去讨论,这里不适合发代码。
|
7
mringg 2014-12-10 16:23:36 +08:00 via Android
用子查询速度肯定慢
|