简体   繁体   English

在MySQL中以特定方式进行数据透视表

[英]Pivot table in a specific way in MySQL

There are other pivot table questions but I can't seem to find an answer to my question. 枢纽分析表还有其他问题,但我似乎找不到答案。

This is my table 这是我的桌子

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

Etc. 等等。

I would like to output it with a query to: 我想将其与查询一起输出到:

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

So in short, the question column holds questions that are not unique (in this demo there are 2 entries (see RECORDID)) so they need to be grouped and sorted by sortorder. 简而言之,问题列包含的问题不是唯一的(在此演示中,有2个条目(请参阅RECORDID)),因此需要对它们进行排序和排序。 RECORDID is always unique RECORDID始终是唯一的

I've seen some pivot/unpivot examples but can't get my head around it. 我已经看过一些枢轴/非枢轴的示例,但无法理解。 Can someone help me with this? 有人可以帮我弄这个吗?

This should do the trick. 这应该可以解决问题。 In the inner query you get only the answers for the specific question and in the outer query when you group by the recordid you get rid of the null values... Try running only the inner query to get the idea. 在内部查询中,您仅获得特定问题的答案;在外部查询中,当您按recordid分组时,您将摆脱空值...尝试仅运行内部查询以了解主意。

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

Let me know if you have any quesitons! 让我知道您是否有任何疑问!

EDIT: Your comment adds another level of complexity :) Now I see how we can use that sort order column... We need one more inner query to get the questions and their sort order. 编辑:您的评论增加了另一层次的复杂性:)现在,我了解如何使用该排序顺序列...我们还需要一个内部查询来获取问题及其排序顺序。 Then get the answers per each sort order and then group by the record id to filter out the nulls and get the desired result. 然后按每个排序顺序获取答案,然后按记录ID分组以过滤出空值并获得所需的结果。 Please try this out and let me know how it goes... The number of questions in the select statements has to be equal to the number of questions of the form which has the most questions - I've put in 8 just to show you that this should not constrain you. 请尝试一下,让我知道它的运行情况。select语句中的问题数量必须等于问题最多的表单中的问题数量-我输入8只是为了向您展示不应限制您。 Now you won't depend on the question name - just the sort numbering. 现在,您将不再依赖问题名称-只需排序编号即可。 It's good that you have the sort order - otherwise you'd have to generate a row number per each record id... 拥有排序顺序很好-否则您必须为每个记录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

Thank you all (especially Koshera!), with some tweaking I got it to work the way I wanted it. 谢谢大家(尤其是Koshera!),通过一些调整,我使它按照我想要的方式工作。

This is the total code (raw, proof of concept;)). 这是总代码(原始的概念证明;)。 The function processQuery is a try / catch PDO execution with parameterized query (see the ? placeholder, the "raw" $i shouldn't be a problem?). 函数processQuery是使用参数化查询的try / catch PDO执行(请参见?占位符,“原始” $ 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM