[英]What is the best way to query this?
我有看起來像這樣的表:
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
我想得到的是一個可以 output 這個查詢:
Q1 A1 1,2 A2 3,4
Q2 A3 5,6 A4 7,8
幾天來我一直在拉頭發,試圖弄清楚這一點。 我在 PHP 和 MySQL 中這樣做,所以如果有人可以在那里闡明一些觀點,那就太好了。
編輯:我忘了提到我也在為此使用 CodeIgniter 。 所以,這可能有助於答案。
考慮到每個問題可能有隨機數量的答案,您無法設計一個返回固定數量列的查詢。 您必須為每個問題返回一個結果,然后在代碼中進行一些解析。
GROUP_CONCAT
function 可以幫助解決此類問題:
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
值。 您可以使用GROUP_CONCAT
function 的ORDER BY
子句對每個答案的返回結果中的答案進行排序(這里我按答案 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)
我為插圖添加了第二個問題的答案。
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;
}
請注意,此代碼仍需要一些工作......它可以讓您了解如何執行此操作。
這個查詢:
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 中並不容易,這取決於您擁有的數據。 例如,如果一個問題的答案超過 2 個,應該顯示什么?
為什么結果會是這樣:
| 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.