使用group by的SQL查询并依赖连接中的某些行

时间:2016-02-24 16:24:10

标签: sql oracle

首先,我在我的数据库中有这些:

TABLE ser_survey
 snum|       title|startdate|   enddate|
 ----------------------------------------
    1|  1st survey| 14/02/24|  14/02/26| 
    2|  2nd survey| 14/03/24|  14/03/26|

TABLE ser_question
snum|qnum| question|       ans1|       ans2|       ans3|       ans4|       ans5|
 -------------------------------------------------------------------------------
   1|   1|     1stQ|  1 of 1stQ|  2 of 1stQ|  3 of 1stQ|  4 of 1stQ|  5 of 1stQ|
   1|   2|     2ndQ|  1 of 2ndQ|  2 of 2ndQ|  3 of 2ndQ|  4 of 2ndQ|  5 of 2ndQ|
   1|   3|     3rdQ|  1 of 3rdQ|  2 of 3rdQ|  3 of 3rdQ|  4 of 3rdQ|  5 of 3rdQ|
   1|   4|     4thQ|  1 of 4thQ|  2 of 4thQ|  3 of 4thQ|  4 of 4thQ|  5 of 4thQ|
   1|   5|     5thQ|  1 of 5thQ|  2 of 5thQ|  3 of 5thQ|  4 of 5thQ|  5 of 5thQ|

TABLE ser_answer
 ID| snum|qnum| ans|<-- ans is a number I gave to each radio button(total 5 radio buttons -->
--------------------
aaa|    1|   1|   5|    <--user id 'aaa' clicked 5th radio button for the 
aaa|    1|   2|   4|         1st question of the 1st survey -->
aaa|    1|   3|   3|
aaa|    1|   4|   2|
aaa|    1|   5|   1|
bbb|    1|   5|   1|
bbb|    1|   1|   5|
bbb|    1|   2|   4|
bbb|    1|   3|   3|
bbb|    1|   4|   2|
ccc|    1|   1|   5|
ccc|    1|   2|   3|
ccc|    1|   3|   3|
ccc|    1|   4|   4|
ccc|    1|   5|   5|

我想要得到的结果是:

snum|qnum|     ans1|cnt1|     ans2|cnt2|     ans3|cnt3|      ans4|cnt4|      ans5|cnt5|
-----------------------------------------------------------------------------------------
   1|   1|1 of 1stQ|   0|2 of 1stQ|   0|3 of 1stQ|   0| 4 of 1stQ|   0| 5 of 1stQ|   3|
   1|   1|1 of 2ndQ|   0|2 of 2ndQ|   0|3 of 2ndQ|   1| 4 of 2ndQ|   2| 5 of 2ndQ|   0|
   1|   1|1 of 3rdQ|   0|2 of 3rdQ|   0|3 of 3rdQ|   3| 4 of 3rdQ|   0| 5 of 3rdQ|   0|
   1|   1|1 of 4thQ|   0|2 of 4thQ|   2|3 of 4thQ|   0| 4 of 4thQ|   1| 5 of 4thQ|   0|
   1|   1|1 of 5thQ|   1|2 of 5thQ|   0|3 of 5thQ|   0| 4 of 5thQ|   0| 5 of 5thQ|   2|

<--cnt here is a number of how many people clicked(answered) 
    the certain radio button. 
    So for example, 3 people clicked 
    5th radio button(ans5) of the 1st question in the 1st survey.--> 

我尝试了很多东西,这是我能提出的唯一一个问题:

 SELECT snum, qnum, ans1, (SELECT COUNT(ans) FROM ser_answer WHERE snum = 1 AND qnum = 1 AND ans = 1) cnt1
            , ans2, (SELECT COUNT(ans) FROM ser_answer WHERE snum = 1 AND qnum = 1 AND ans = 2) cnt2
            , ans3, (SELECT COUNT(ans) FROM ser_answer WHERE snum = 1 AND qnum = 1 AND ans = 3) cnt3
            , ans4, (SELECT COUNT(ans) FROM ser_answer WHERE snum = 1 AND qnum = 1 AND ans = 4) cnt4
            , ans5, (SELECT COUNT(ans) FROM ser_answer WHERE snum = 1 AND qnum = 1 AND ans = 5) cnt5
 FROM ser_question
 WHERE snum = 1 AND qnum = 1

这只给了我想要的第一行结果。 是否有另一种/更好的方式来获得我想要的东西?

1 个答案:

答案 0 :(得分:1)

以下是您在一次查询中的操作方法。

 select snum, qnum,
        ans1,
        sum(CASE WHEN ans=1 THEN 1 ELSE 0 END) as cnt1,
        ans2,
        sum(CASE WHEN ans=2 THEN 1 ELSE 0 END) as cnt2,
        ans3,
        sum(CASE WHEN ans=3 THEN 1 ELSE 0 END) as cnt3,
        ans4,
        sum(CASE WHEN ans=4 THEN 1 ELSE 0 END) as cnt4,
        ans5,
        sum(CASE WHEN ans=5 THEN 1 ELSE 0 END) as cnt5
 from ser_answer
 join ser_question on ser_answer.snum = ser_question.snum and ser_answer.qnum = ser_question.qnum
 group by snum, qnum, ans1, ans2, ans3, ans4, ans5

这里有两个(我认为更清楚,但我必须写第一个看到它)

select snum, qnum, ans1, cnt1, ans2, cnt2, ans3, cnt3, ans4, cnt4, ans5, cnt5
 from (
  select snum, qnum,
         sum(CASE WHEN ans=1 THEN 1 ELSE 0 END) as cnt1,
         sum(CASE WHEN ans=2 THEN 1 ELSE 0 END) as cnt2,
         sum(CASE WHEN ans=3 THEN 1 ELSE 0 END) as cnt3,
         sum(CASE WHEN ans=4 THEN 1 ELSE 0 END) as cnt4,
         sum(CASE WHEN ans=5 THEN 1 ELSE 0 END) as cnt5
  from ser_answer
  group by snum, qnum
 ) answer_count
 join ser_question on answer_count.snum = ser_question.snum and answer_count.qnum = ser_question.qnum

你也可以重写第一个查询来使用窗口函数,但不需要它,我想你明白了。