Я делаю обзор с PHP и MySQL. Я испытываю затруднения при выяснении что метод использовать для отображения случайного ряда 10 вопросов и их ответов. Каждый вопрос может иметь между 2 и 5 ответами.
Вот то, как база данных настраивается:
questions:
ID | quID | question
answers:
ID | an_quID | anID | answer
фунт стерлингов и an_quID соединяют таблицы.
Если я делаю следующее (не точный код; отредактированный для краткости). Я заканчиваю тем, что делал 20 вызовов базы данных.
$sql = "SELECT * FROM questions ORDER BY RAND() LIMIT 10";
while($row = mysql_fetch_array($result)) {
$quID = $row[quID];
echo "HTML code here";
"SELECT * FROM answers WHERE an_quID = '$quID'"
while($inside_row = mysql_fetch_array($inside_result)) {
$answer = $inside_row[answer];
echo "HTML code here";
}
}
Я также попытался использовать array_push (), со всего 2 вызовами базы данных, продвинуть все результаты в массивы. Но проблема с array_push состоит в том, что, насколько я могу сказать, Вы не можете сделать ассоциативные массивы, где Вы указываете ключи.
Каков был бы идеальный способ отобразить случайный ряд 10 вопросов и их ответы?
Вместо одного вызова на вопрос для получения ответов, вы можете извлечь все идентификаторы вопросов и использовать синтаксис IN () в MySQL для получения всех ответов сразу. Затем выполните цикл, чтобы сгладить данные по своему усмотрению
SELECT * FROM answers WHERE an_quID IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Вам не нужно столько идентификаторов, по одному для каждой таблицы, и может быть много ответов на вопрос, поэтому нам нужно неуникальное поле в ответах, указывающее на id вопроса:
questions:
id | question
answers:
id | id_questions | answer | correct
А запросы к базе данных в циклах (в 99% случаев) - это плохо.
Получите вопросы и используйте WHERE IN с идентификаторами вопросов, например, чтобы получить нужные записи.
Базовый рабочий пример:
/** Tables
CREATE TABLE `questions` (
`id` INT NOT NULL AUTO_INCREMENT,
`question` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE = MyISAM;
CREATE TABLE `test`.`answers` (
`id` INT NOT NULL AUTO_INCREMENT,
`id_questions` INT NOT NULL,
`answer` VARCHAR(255) NOT NULL,
`correct` BOOL NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE = MyISAM;
*/
/** Test Data
INSERT INTO `questions` (id,question) VALUES
(null,'Pick A!'),(null,'Pick B!'),(null,'Pick C!'),(null,'Pick D!');
INSERT INTO `answers` (id,id_questions,answer,correct) VALUES
(null,1,'Answer A',1),(null,1,'Answer B',0),(null,1,'Answer C',0),(null,1,'Answer D',0),
(null,2,'Answer A',0),(null,2,'Answer B',1),(null,2,'Answer C',0),(null,2,'Answer D',0),
(null,3,'Answer A',0),(null,3,'Answer B',0),(null,3,'Answer C',1),(null,3,'Answer D',0),
(null,4,'Answer A',0),(null,4,'Answer B',0),(null,4,'Answer C',0),(null,4,'Answer D',1);
*/
define('NUM_OF_QUESTIONS_TO_DISPLAY',3);
// DB login data
$db_login = array('host' => 'localhost',
'user' => 'test',
'pass' => 'tset',
'base' => 'test'
);
// DB connect
$db = new mysqli($db_login['host'],$db_login['user'],$db_login['pass'],$db_login['base']);
if (mysqli_connect_errno())
trigger_error('DB connection failed: '.mysqli_connect_errno());
// Get questions
if ($res = $db->query('SELECT q.id, q.question FROM questions q
ORDER BY RAND() LIMIT '.(int)NUM_OF_QUESTIONS_TO_DISPLAY.';')) {
$questions = array();
$questions_ids = array();
while ($r = $res->fetch_assoc()) {
$questions[] = $r;
$questions_ids[] = $r['id'];
}
}
// Get the answers
if ($res = $db->query('SELECT a.id_questions, a.answer, a.correct FROM answers a
WHERE (a.id_questions IN ('.implode(',',$questions_ids).'))
ORDER BY RAND();')) {
$answers = array();
while ($r = $res->fetch_assoc())
$answers[$r['id_questions']][] = $r;
}
?>
<html>
<head>
<title>Foo!</title>
</head>
<body style="margin: 100px;">
<?php foreach ($questions as $question) : ?>
<strong><?php echo $question['question']; ?></strong>
<small>(Question id:<?php echo $question['id']; ?>)</small>
<ul>
<?php foreach ($answers[$question['id']] as $answer) : ?>
<li><?php echo $answer['answer'].($answer['correct'] ? '(*)' : ''); ?></li>
<?php endforeach; ?>
</ul>
<?php endforeach; ?>
</body>
</html>
(Не готовый сценарий, но он должен помочь вам с проблемами, с которыми у вас возникли проблемы)
Что-то вроде этого:
SELECT * FROM questions AS q INNER JOIN answers AS a ON q.quID = a.an_quID
ORDER BY RAND() LIMIT 10
Затем в своем коде вы можете отфильтровать результаты на основе строк, возвращенных с тем же quID
Джоштоник действительно близок. Я бы сделал что-то вроде этого:
SELECT * FROM answers WHERE an_quID IN (SELECT quID FROM questions ORDER BY RAND() LIMIT 10);
Как сказал Кучен, вам нужно немного нормализовать свою БД. Вы не должны использовать id и question_id (id должно быть всем, что вам нужно);