Mysql 查询语句怎么写? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xiyangyang
V2EX    问与答

Mysql 查询语句怎么写?

  •  
  •   xiyangyang 2014-12-10 10:58:12 +08:00 4239 次点击
    这是一个创建于 4047 天前的主题,其中的信息可能已经有所发展或是发生改变。

    开发市场调查业务,有一个调查问题表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高手,有没有办法能加快计算速度。

    7 条回复    2014-12-10 16:23:36 +08:00
    cye3s
        1
    cye3s  
       2014-12-10 11:37:46 +08:00 via Android
    那么多子查询,快就怪了,先用sum(case...l
    )语句转横表,就是每人一行记录,包含所有问题回答,试试
    xiyangyang
        2
    xiyangyang  
    OP
       2014-12-10 12:09:13 +08:00
    对mysql不熟悉,但是要求比较急,可否请大侠写这个sql语句?谢谢了。
    airylinus
        3
    airylinus  
       2014-12-10 13:04:25 +08:00
    最简单的加速方法是用视图,怎么用查 MySQL 文档。
    另外,还可以把每个问题的答案转换成二进制,用二进制运算替代子查询。
    tranch
        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))
    xiyangyang
        5
    xiyangyang  
    OP
       2014-12-10 13:39:13 +08:00
    tranch:
    我们想要的是,知道有多少个这样的被调查者,他回答的问题满足这样的条件:Q2A in (1,8,9) 并且Q2B in (1,8,9), .....
    所以,question_label IN ("Q2A", "Q2B", 。。。。。。), 这样是不对的

    airylinus:
    每个问题的答案都是1到10的整数,没法转换成二进制,因为其他的计算公式还需要他们呢。
    tranch
        6
    tranch  
       2014-12-10 13:43:33 +08:00
    建议把以上问题贴到问答网站(比如 segmentfault.com)上去讨论,这里不适合发代码。
    ming2050
        7
    ming2050  
       2014-12-10 16:23:36 +08:00 via Android
    用子查询速度肯定慢
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5617 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 03:10 PVG 11:10 LAX 19:10 JFK 22:10
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86