我的表格看起来像这样:
questions:
id description
1 Q1
2 Q2
answers:
id question_id x y description
1 1 1 2 A1
2 1 3 4 A2
3 2 5 6 A3
4 2 7 8 A4
我想要的是一个可以输出的查询:
Q1 A1 1,2 A2 3,4
Q2 A3 5,6 A4 7,8
我一直在拉我的头发好几天试图解决这个问题。我在PHP和MySQL中这样做,所以如果有人能在那里发光,那真的很棒。
编辑:我忘了提到我也在使用CodeIgniter。所以,这可能有助于解答。答案 0 :(得分:2)
考虑到每个问题可能存在随机数量的答案,您无法设计将返回固定数量列的查询。您必须为每个问题返回一个结果,然后在代码中进行一些解析。
GROUP_CONCAT
函数可能对此类问题有所帮助:
SELECT q.description, GROUP_CONCAT(
CONCAT(a.description,' ',a.x,',',a.y) ORDER BY a.id
SEPARATOR ' '
) AS answers
FROM questions q
JOIN answers a ON a.question_id = q.id
GROUP BY q.description;
将返回
+-------------+---------------+
| description | answers |
+-------------+---------------+
| Q1 | A1 1,2 A2 3,4 |
| Q2 | A3 5,6 A4 7,8 |
+-------------+---------------+
2 rows in set (0.00 sec)
您可以通过在代码中解析结果的任何内容来更改SEPARATOR
值。您可以使用ORDER BY
函数的GROUP_CONCAT
子句在每个答案的返回结果中排序答案(此处我按答案ID排序)。
修改:如果您确定每个问题的答案永远不会超过4个,您可以发出以下查询,将每个答案放在自己的列中:
SELECT description,
REPLACE(SUBSTRING(SUBSTRING_INDEX(answers, '$', 1), LENGTH(SUBSTRING_INDEX(answers, '$', 1 - 1)) + 1), '$', '') answer_1,
REPLACE(SUBSTRING(SUBSTRING_INDEX(answers, '$', 2), LENGTH(SUBSTRING_INDEX(answers, '$', 2 - 1)) + 1), '$', '') answer_2,
REPLACE(SUBSTRING(SUBSTRING_INDEX(answers, '$', 3), LENGTH(SUBSTRING_INDEX(answers, '$', 3 - 1)) + 1), '$', '') answer_3,
REPLACE(SUBSTRING(SUBSTRING_INDEX(answers, '$', 4), LENGTH(SUBSTRING_INDEX(answers, '$', 4 - 1)) + 1), '$', '') answer_4
FROM (
SELECT q.description, GROUP_CONCAT(
CONCAT(a.description,' ',a.x,',',a.y) ORDER BY a.id
SEPARATOR '$'
) AS answers
FROM questions q
JOIN answers a ON a.question_id = q.id
GROUP BY q.description
) t;
将返回
+-------------+----------+----------+----------+----------+
| description | answer_1 | answer_2 | answer_3 | answer_4 |
+-------------+----------+----------+----------+----------+
| Q1 | A1 1,2 | A2 3,4 | | |
| Q2 | A3 5,6 | A4 7,8 | A5 9,10 | |
+-------------+----------+----------+----------+----------+
2 rows in set (0.00 sec)
我为第二个问题添加了答案。
答案 1 :(得分:1)
select * from answers ORDER BY question_id
$question_id = 0;
$print_ln = null;
foreach ($result as $row) {
if ($question_id != $row['question_id']) {
echo "<br>";
$question_id = $row['question_id'];
$print_ln = "Q" . $row['question_id'] . " " . $row['description'] . " " . $row['x'] . "," . $row['y'];
} else {
$print_ln = $print_ln . " " . $row['description'] . " " . $row['x'] . "," . $row['y'];
}
echo $print_ln;
}
请注意,此代码仍需要一些工作......它可以让您了解如何执行此操作。
答案 2 :(得分:0)
此查询:
SELECT
q.id
, q.description
, a.description
, CONCAT(a.x, ',', a.y)
FROM questions AS q
JOIN answers AS a
ON a.question_id = q.id
ORDER BY q.id
, a.id
将显示:
| 1 | Q1 | A1 | 1,2 |
| 1 | Q1 | A2 | 3,4 |
| 2 | Q2 | A3 | 5,6 |
| 2 | Q2 | A4 | 7,8 |
您所描述的最终结果称为旋转,在MySQL中并不容易,取决于您拥有的数据。例如,对于一个问题,应该显示什么,有两个以上的答案?
为什么结果如此:
| Q1 | A1 | 1,2 | A2 | 3,4 |
| Q2 | A3 | 5,6 | A4 | 7,8 |
而不是那样?:
| Q1 | A1 | 1,2 | A2 | 3,4 |
| Q2 | A4 | 7,8 | A3 | 5,6 |
无论如何,每个问题最多4个答案并按answers.id
排序,这将有效。尽管使用上一个查询并在PHP中进行透视可能是最好的,您可以在这里处理可变数量的列而没有问题:
SELECT
q.id
, q.description
, ( SELECT a.description
FROM answers AS a
WHERE a.question_id = q.id
ORDER BY a.id LIMIT 0,1
) AS answer1
, ( SELECT CONCAT(a.x, ',', a.y)
FROM answers AS a
WHERE a.question_id = q.id
ORDER BY a.id LIMIT 0,1
) AS xy1
, ( SELECT a.description
FROM answers AS a
WHERE a.question_id = q.id
ORDER BY a.id LIMIT 1,1
) AS answer2
, ( SELECT CONCAT(a.x, ',', a.y)
FROM answers AS a
WHERE a.question_id = q.id
ORDER BY a.id LIMIT 1,1
) AS xy2
, ( SELECT a.description
FROM answers AS a
WHERE a.question_id = q.id
ORDER BY a.id LIMIT 2,1
) AS answer3
, ( SELECT CONCAT(a.x, ',', a.y)
FROM answers AS a
WHERE a.question_id = q.id
ORDER BY a.id LIMIT 2,1
) AS xy3
, ( SELECT a.description
FROM answers AS a
WHERE a.question_id = q.id
ORDER BY a.id LIMIT 3,1
) AS answer4
, ( SELECT CONCAT(a.x, ',', a.y)
FROM answers AS a
WHERE a.question_id = q.id
ORDER BY a.id LIMIT 3,1
) AS xy4
FROM questions AS q
ORDER BY q.id