可以改进总结调查数据的SQLite3查询吗?

时间:2016-03-01 10:34:16

标签: sql sqlite

鉴于以下表格模式描述了受访者对包含问题(Q1,Q2..Qn)的调查的回应,每个问题都有多项选择答案(Q1a1,Q1a2,Q2a1 ......):

respondent | group | Q1   | Q2   | ... Qn
  fred     |  xyz  | Q1a1 | Q2a3 | ...
   joe     |  xyz  | Q1a2 | q2a1 | ...
  bill     |  abc  | Q1a1 | Q2a4 | ...

在一个简单的问题中,Q1a1可能为“是”而Q1a2可能为“否”,但认为答案是任何简单的文本字符串,这些字符串在源数据中存在(可能但未使用的答案的可能性可以被忽略了。)

每一行代表一个独特的受访者,每组中有许多受访者。每个受访者回答每个问题,给出每个问题的有效答案之一。

我想根据每个小组将每个答案的每个答案中有多少(可能没有)列表:我想要制作:

group | Q1_a1 | Q1_a2 | Q1_a3 | Q2_a1 | Q2_a2 | Q3_a1 | ...
 xyz  |  32   |  12   |   9   |  11   |   23  |   2   | ...
 abc  |  27   |   6   |       |  18   |   12  |  26   | ...

我想在sqlite3 中执行此操作,并且我有一个我认为有效的查询,但我也认为它很笨拙并且无法很好地扩展到大量问题:

WITH Q1YES AS (SELECT RespondentGroup, COUNT(*) AS yes FROM DATA
                 WHERE Q1 = 'Yes'
                 GROUP BY RespondentGroup),
     Q1NO   AS (SELECT RespondentGroup, COUNT(*) AS no FROM DATA
                 WHERE Q1 = 'No'
                 GROUP BY RespondentGroup),

     Q2YES  AS (SELECT RespondentGroup, COUNT(*) AS yes FROM DATA
                 WHERE Q2 = 'Yes'
                 GROUP BY RespondentGroup),
     Q2NO   AS (SELECT RespondentGroup, COUNT(*) AS no FROM DATA
                 WHERE Q2 = 'No'
                 GROUP BY RespondentGroup),
     Q2PART AS (SELECT RespondentGroup, COUNT(*) AS part FROM DATA
                 WHERE Q2 = 'Part'
                 GROUP BY RespondentGroup)                                                                                                                    

SELECT DISTINCT DATA.RespondentGroup as RespondentGroup,
        Q1YES.yes as "Q1 Yes", Q1NO.no as "Q1 No",
        Q2YES.yes as "Q2 Yes", Q2NO.no as "Q2 No", Q2PART.part as "Q2 Part"

  FROM DATA
  LEFT OUTER JOIN Q1YES  on Q1YES.RespondentGroup   = DATA.RespondentGroup
  LEFT OUTER JOIN Q1NO   on Q1NO.RespondentGroup    = DATA.RespondentGroup

  LEFT OUTER JOIN Q2YES  on Q2YES.RespondentGroup   = DATA.RespondentGroup
  LEFT OUTER JOIN Q2NO   on Q2NO.RespondentGroup    = DATA.RespondentGroup
  LEFT OUTER JOIN Q2PART on Q2PART.RespondentGroup  = DATA.RespondentGroup

ORDER BY RespondentGroup;

可以改进此查询(答案必须在SQLite3中运行)吗?

1 个答案:

答案 0 :(得分:1)

也许这个?

select DATA.Respondentgroup as RespondentGroup
  , sum( case Q1 when 'Yes' then 1 else 0 end  ) as Q1Yes
  , sum( case Q1 when 'No' then 1 else 0 end  ) as Q1No
  , sum( case Q2 when 'Yes' then 1 else 0 end  ) as Q2Yes
  , sum( case Q2 when 'No' then 1 else 0 end  ) as Q2No
  , sum( case Q2 when 'Part' then 1 else 0 end  ) as Q2Part

From DATA
group by DATA.Respondentgroup
order by 1