在 MySQL 中以特定方式旋转 table
Pivot table in a specific way in MySQL
还有其他关键 table 问题,但我似乎找不到问题的答案。
这是我的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
等等
我想通过查询将其输出到:
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)),因此需要按排序顺序对它们进行分组和排序。 RECORDID 始终是唯一的
我看过一些 pivot/unpivot 示例,但无法理解。
有人可以帮我解决这个问题吗?
这应该可以解决问题。在内部查询中,您仅获得特定问题的答案,而在外部查询中,当您按 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
如果您有任何问题,请告诉我!
编辑:您的评论增加了另一层复杂性 :) 现在我明白了我们如何使用该排序顺序列...我们需要一个更多的内部查询来获取问题及其排序顺序。然后根据每个排序顺序获取答案,然后按记录 ID 分组以过滤掉空值并获得所需的结果。请试一试,让我知道结果如何... select 语句中的问题数量必须等于问题最多的表格的问题数量 - 我输入了 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
谢谢大家(尤其是 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>
还有其他关键 table 问题,但我似乎找不到问题的答案。
这是我的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
等等
我想通过查询将其输出到:
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)),因此需要按排序顺序对它们进行分组和排序。 RECORDID 始终是唯一的
我看过一些 pivot/unpivot 示例,但无法理解。 有人可以帮我解决这个问题吗?
这应该可以解决问题。在内部查询中,您仅获得特定问题的答案,而在外部查询中,当您按 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
如果您有任何问题,请告诉我!
编辑:您的评论增加了另一层复杂性 :) 现在我明白了我们如何使用该排序顺序列...我们需要一个更多的内部查询来获取问题及其排序顺序。然后根据每个排序顺序获取答案,然后按记录 ID 分组以过滤掉空值并获得所需的结果。请试一试,让我知道结果如何... select 语句中的问题数量必须等于问题最多的表格的问题数量 - 我输入了 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
谢谢大家(尤其是 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>