在MySQL中以特定方式透视表

时间:2016-06-02 14:39:57

标签: php mysql sql pivot

还有其他数据透视表问题,但我似乎无法找到问题的答案。

这是我的表

ID    QUESTION       ANSWER       RECORDID      SORTORDER
1     Question 1     Answer 1.1   123456        1
2     Question 2     Answer 2.1   123456        2
3     Question 3     Answer 3.1   123456        3
4     Question 1     Answer 1.2   654321        1
5     Question 2     Answer 2.2   654321        2
6     Question 3     Answer 3.2   654321        3

我想用查询输出:

Question 1    Question 2    Question 3
Answer 1.1    Answer 2.1    Answer 3.1
Answer 1.2    Answer 2.2    Answer 3.2

简而言之,问题列包含的问题不是唯一的(在此演示中有2个条目(请参阅RECORDID))因此需要对它们进行分组并按sortorder排序。 RECORDID始终是唯一的

我已经看过一些转轴/未转动的例子,但无法理解它。 有人可以帮我这个吗?

2 个答案:

答案 0 :(得分:1)

这应该可以解决问题。在内部查询中,您只获得特定问题的答案,在外部查询中,当您按记录组分组时,您可以删除空值...尝试仅运行内部查询以获取想法。

select  
  max(q.Question1),
  max(q.Question2),
  max(q.Question3) FROM (SELECT     
                         recordid,
                         case when question = 'Question 1' then answer else null end as Question1, 
                         case when question = 'Question 2' then answer else null end as Question2, 
                         case when question = 'Question 3' then answer else null end as Question3 FROM questions) q group by q.recordid

如果您有任何疑问,请告诉我!

编辑:你的评论增加了另一个复杂程度:)现在我看到我们如何使用该排序顺序列......我们需要一个更多的内部查询来获取问题及其排序顺序。然后根据每个排序顺序获取答案,然后按记录ID分组以过滤掉空值并获得所需的结果。请尝试一下,让我知道它是怎么回事......选择陈述中的问题数量必须等于问题最多的表格问题的数量 - 我已经将8个问题放入告诉你这不应该限制你。现在你不依赖于问题名称 - 只是排序编号。您有排序顺序很好 - 否则您必须为每个记录ID生成一个行号...

SET @rank=0; SET @id:=0; select recordid, max(qq.question1) as 'Question 1', max(qq.question2) as 'Question 2', max(qq.question3) as 'Question 3', max(qq.question4) as 'Question 4', max(qq.question5) as 'Question 5', max(qq.question6) as 'Question 6', max(qq.question7) as 'Question 7', max(qq.question8) as 'Question 8' FROM ( SELECT recordid, case when q.rownumber = 1 then CONCAT(question,': ', answer) else null end as question1, case when q.rownumber = 2 then CONCAT(question,': ', answer) else null end as question2, case when q.rownumber = 3 then CONCAT(question,': ', answer) else null end as question3, case when q.rownumber = 4 then CONCAT(question,': ', answer) else null end as question4, case when q.rownumber = 5 then CONCAT(question,': ', answer) else null end as question5, case when q.rownumber = 6 then CONCAT(question,': ', answer) else null end as question6, case when q.rownumber = 7 then CONCAT(question,': ', answer) else null end as question7, case when q.rownumber = 8 then CONCAT(question,': ', answer) else null end as question8 FROM( select recordid, question, answer, sortorder, @rank:=CASE WHEN @id=recordid THEN @rank+1 ELSE 1 END as rownumber, @id:=recordid from questions order by recordid, sortorder ) q )qq GROUP BY recordid

答案 1 :(得分:1)

谢谢大家(特别是Koshera!),经过一些调整,我按照我想要的方式工作。

这是总代码(原始,概念验证;))。 函数processQuery是一个带参数化查询的try / catch PDO执行(参见?占位符," raw" $ i不应该是一个问题?)。

<div class="database-container">
<table border="0" cellspacing="0" cellpadding="7">
<tr>

<?php

// get all questions and group them so we only get unique questions
$getQuestions = processQuery("SELECT ansr_question FROM forms_123456 WHERE is_answer=1 and ansr_type != 'text' GROUP BY ansr_question ORDER BY ansr_sortorder ASC",$param,'fetch-raw',$server,$extra,$DBH);
unset($param);

// fetch all the questions
while($fetchQuestions = $getQuestions->fetch())

    {

        // save into array and generate the column questions
        $questions[] = $fetchQuestions["ansr_question"];
        $question_headers .= '<td height="19" nowrap style="background-color:#e9e9e9; font-weight:400;">'.trim(ucfirst($fetchQuestions["ansr_question"])).'</td>';

    }

// loop array
$num_questions = count($questions);
$num_questions_check = $num_questions -1;
for($i=0; $num_questions > $i; ++$i)

    {

    // prepare PDO params
    $param[] = $questions[$i];

    // use the count to perform if statement when last question has been reached
    $comma = ',';
    if($num_questions_check == $i)

        {
        $comma = '';
        }

    // generate the 2 dynamic parts of the query
    $sql_part1 .= "max(qq.question$i) as 'answer$i',";
    $sql_part2 .= "case when q.ansr_question = ? then ansr_answer else null end as question$i$comma ";

    }


// make it 1 query
$query = "select 
$sql_part1
ansr_recordid, 
ansr_type
FROM (
    SELECT
        ansr_recordid, 
        ansr_type,
        $sql_part2
    FROM(
        select 
            ansr_recordid, 
            ansr_question,
            ansr_answer,
            ansr_type,
            ansr_sortorder
            from forms_123456 where is_answer=1 order by ansr_recordid, ansr_sortorder 
            ) q
    )qq
GROUP BY ansr_recordid";

// lets try it!
$getAnswers = processQuery($query,$param,'fetch-raw',$server,$extra,$DBH);
unset($param);


// show questions and other data
echo '<td height="19" nowrap style="background-color:#e9e9e9; font-weight:600;">Status</td>
    <td height="19" nowrap style="background-color:#e9e9e9; font-weight:600;">Details</td>';

echo $question_headers;

echo '<td height="19" nowrap style="background-color:#e9e9e9; font-weight:600;">Record ID</td>
    <td height="19" nowrap style="background-color:#e9e9e9; font-weight:600;">Start Date</td>
    <td height="19" nowrap style="background-color:#e9e9e9; font-weight:600;">End Date</td>
</tr>';


// show values ----------------------------------------
$first = 1;
while($fetch = $getAnswers->fetch())

{

// change color per row
if($first == 0)

    {
    $first = 1;
    $bgcolor = '#f1f1f1';
    }
else
    {
    $first = 0;
    $bgcolor = '';
    }

echo '<tr>';

echo '<td height="19" nowrap style="background-color:'.$bgcolor.'; font-weight:400;">OK</td>
    <td height="19" nowrap style="background-color:'.$bgcolor.'; font-weight:400;">Bekijken</td>';

// loop the number of questions so we get the same amount of columns
for($i=0; $num_questions > $i; ++$i)

    {
    echo '<td height="19" nowrap style="background-color:'.$bgcolor.'; font-weight:400;">'.trim(ucfirst($fetch["answer$i"])).'</td>';
    }

echo '<td height="19" nowrap style="background-color:'.$bgcolor.'; font-weight:400;">'.$fetch["ansr_recordid"].'</td>
    <td height="19" nowrap style="background-color:'.$bgcolor.'; font-weight:400;">Start Date</td>
    <td height="19" nowrap style="background-color:'.$bgcolor.'; font-weight:400;">End Date</td>';

echo '</tr>';

}

?>

</table>
</div>