So I am working on a project where I have a database filled with questions/options. Each question has 3 options (1 of them is right).
Before a user starts a quiz he selects how many questions he wants to have. I do this with a select form. PHP then sends value from select form to the quiz page. Where it's used in SQL query:
SELECT *
FROM quiz_question
WHERE quiz_id = 1
ORDER BY RAND()
LIMIT $number
The $number stands for value of select form
I can display questions but not options for the selected question.
My code:
<div id="quiz">
<?php
$number = $_POST['number'];
$sql = "SELECT *
FROM quiz_question
WHERE quiz_id = 1
ORDER BY RAND()
LIMIT $number";
$result = mysqli_query($conn,$sql);
if (mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_assoc($result)) {
echo "<p>";
echo $row['question'];
echo "</p>";
}
}
?>
</div>
My database looks something like this:
quiz
id (PK)
quiz_name (text)
quiz_question
id (PK)
quiz_id (FK)
question (text)
quiz_question_option
id (PK)
quiz_question_id (FK)
quiz_option (text)
is_correct (enum 0, 1)
EDIT:
I tried to use INNER JOIN but when I used ORDER BY RAND() and LIMIT I couldn't get all 3 options for a single question.
Just put aside SQL injection issue (you should use prepared statement), here is how you can use a secondary query to get all the options of the quiz for rendering.
<div id="quiz">
<?php
// aggregate an array of options
$option_results = mysqli_query($conn, "SELECT qo.* FROM quiz_question_option qo
LEFT JOIN quiz_question q ON (qo.quiz_question_id = q.id)
WHERE q.quiz_id = 1");
$options = [];
while ($option = mysqli_fetch_assoc($option_results)) {
$options[$option['quiz_question_id']] = $option;
}
mysqli_free_result($option_results);
$number = $_POST['number'];
$sql = "SELECT * FROM quiz_question WHERE quiz_id = 1 ORDER BY RAND() LIMIT $number";
$result = mysqli_query($conn,$sql);
if (mysqli_num_rows($result) > 0)
{
while ($question = mysqli_fetch_assoc($result)) {
echo "<p>";
echo $question['question'];
echo "</p>";
}
if (isset($options[$question['id']])) {
echo "<ul>";
foreach ($options[$question['id']] as $option) {
echo $option['quiz_option'];
}
echo "</ul>";
}
}
?>
</div>
Now, to convert to prepared statements:
<div id="quiz">
<?php
$number = $_POST['number'] ?? 10000;
$quiz_id = 1;
// aggregate an array of all questions' options of a quiz
$option_stmts = mysqli_prepare($conn, "SELECT qo.* FROM quiz_question_option qo
LEFT JOIN quiz_question q ON (qo.quiz_question_id = q.id)
WHERE q.quiz_id = ?");
$option_stmts->bind_param('i', $quiz_id);
$option_results = $option_stmts->execute();
$options = [];
while ($option = mysqli_fetch_assoc($option_results)) {
$options[$option['quiz_question_id']] = $option;
}
mysqli_free_result($option_results);
mysqli_stmt_close($option_stmts);
// query for all the questions of a quiz
$stmt = mysqli_prepare($conn, "SELECT * FROM quiz_question WHERE quiz_id = ? ORDER BY RAND() LIMIT ?");
$stmt->bind_param('ii', $quiz_id, $number);
$result = $stmt->execute();
if (mysqli_num_rows($result) > 0)
{
while ($question = mysqli_fetch_assoc($result)) {
echo "<p>";
echo $question['question'];
echo "</p>";
}
if (isset($options[$question['id']])) {
echo "<ul>";
foreach ($options[$question['id']] as $option) {
echo $option['quiz_option'];
}
echo "</ul>";
}
}
?>
</div>
Related
I am creating a webGL game on Unity but want to get my php correct first.
I have 2 tables questions and answers. Each question has 4 potential answers and need to pull these from my db.
The answer table matches with the question table through questionId.
Questions:
Should I better use a table join or should I separate them?
Should I simply have a select statement just for the question table then a
join table for answers and submit separately?
Should I have created
the answer table with 4 columns for different answers?
Current code:
<?php
$query = ("select questiontable.questionId, questiontable.question, answertable.answerId,answertable.answer, answertable.questionId, questiontable.scoreValue
FROM questiontable
inner join answertable on questiontable.questionId=answertable.questionId ORDER BY RAND () LIMIT 1 ");
$result =mysqli_query($conn, $query) or die(mysqli_error($conn));
while ($row = mysqli_fetch_assoc($result)){
$row_cnt = mysqli_num_rows($result);
echo $row_cnt;
echo $row ['question'];
echo $row ['answer'] ;
echo $row ['answer'] ;
echo $row ['answer'];
echo $row ['answer'];
}
?>
Here are my tables:
CREATE TABLE `braingain`.`questionTable`
( `questionId` INT NOT NULL AUTO_INCREMENT , `question` VARCHAR(600) NOT NULL , `scoreValue` INT NOT NULL , `subject` VARCHAR(50) NOT NULL , PRIMARY KEY (`questionId`));
CREATE TABLE `braingain`.`answerTable`
( `answerId` INT NOT NULL , `answer` VARCHAR(600) NOT NULL , 'questionId', isCorrect;
The query should pull questions and 4 associated answers into an array.
Desired result
The created array should look like this:
| question | answerA | answerB | answerC | answerD |
| WHICH IS THE CORRECT SPELLING? | APPLE | APEL | APPUL | APPAL |
Run two nested queries,
$output = array();
$answer_array = array('answerA','answerB','answerC','answerD');
$query = ("select * from questiontable ORDER BY RAND () LIMIT 1 ");
$result =mysqli_query($conn, $query) or die(mysqli_error($conn));
while ($row = mysqli_fetch_assoc($result)){
$row_cnt = mysqli_num_rows($result);
$output['question']=$row['question'];
$query2 = ("select * from answerTable where questionId = ". $row ['questionId'] order by answerId);
$result2 =mysqli_query($conn, $query2) or die(mysqli_error($conn));
$i=0;
while ($row2 = mysqli_fetch_assoc($result2)){
$output[answer_array[$i]]=$row2['answer'];
$i++;
}
}
print_r($output);
?>
Please have a look at indentation, makes code much more plesant :)
<?php
$query = ("
SELECT
questiontable.questionId,
questiontable.question,
answertable.answerId,
answertable.answer,
answertable.questionId,
questiontable.scoreValue
FROM
questiontable
INNER JOIN
answertable on questiontable.questionId = answertable.questionId
ORDER BY RAND()
LIMIT 1
");
$result = mysqli_query($conn, $query) or die(mysqli_error($conn));
$data = [];
$data[] = null;
$keys = [
'question',
'answerA',
'answerB',
'answerC',
'answerD',
];
$return = [];
while ($row = mysqli_fetch_assoc($result)){
if ($data[0] !== $row['question']) {
$data = [];
$data[] = $row['question'];
}
$data[] = $row['answer'];
if (count($data) === 5) {
$dataAssociative = array_combine($keys, $data);
$return[] = $dataAssociative;
}
}
var_dump($return);
?>
ok, so i have everything working with my php etc. i have it echoing the result as i want heres the code...
<?php
session_start();
include 'dbconnect.php';
$output = array();
$answer_array = array('answerA','answerB','answerC','answerD'); //loads answers into array
$query = ("select * from questiontable ORDER BY RAND () LIMIT 1 ");//sql query to get questions
$result =mysqli_query($conn, $query) or die(mysqli_error($conn));
while ($row = mysqli_fetch_assoc($result)){
$row_cnt = mysqli_num_rows($result);
$output['question']=$row['question'];
$query2 = ("select * from answerTable where questionId = '". ($row ['questionId'])."' order by rand()");//sql query to get answers for questions by questionId
$result2 =mysqli_query($conn, $query2) or die(mysqli_error($conn));
$i=0;
$question=$row ['question'];
while ($row2 = mysqli_fetch_assoc($result2)){
$output[$answer_array[$i]]=$row2['answer'];
$i++;
$_POST = $output;
}
}
echo "</br> ";
echo $_POST ['question'];
echo "</br> ";
echo $_POST['answerA'];
echo "</br>";
echo $_POST['answerB'];
echo "</br>";
echo $_POST['answerC'];
echo "</br> ";
echo $_POST['answerD'];
?>
now i need to store the results in unity so i can assign them to buttons etc.
i have it pulling the details but unsure how to assign for example $_POST['answerA]; to a variable in c#.
this is my c# code...
public class qNaDisplay : MonoBehaviour {
public Text questionDisplayText, answerAText, answerBText, answerCText, answerDText;
public Text questMessage, answerMessage;
private string question, a, b, c, d;
// Use this for initialization
void Start ()
{
WWW questionURL = new WWW("http://localhost:8080/Project/PHP/questionRequest.php");
question = questionDisplayText.text;
a = answerAText.text;
b = answerBText.text;
c = answerCText.text;
d = answerDText.text;
StartCoroutine(qNaget(questionURL));
}
// Update is called once per frame
void Update () {
}
private IEnumerator qNaget (WWW questionURL)
{
yield return questionURL;
Debug.Log(questionURL.text);
if (questionURL.error != null)
{
print("There was an error getting the question " + questionURL.error);
}
else
{
Debug.Log (questionURL.text); // this is a GUIText that will display the scores in game.
}
}
}
Hi i'm quite newbie in php language and i need to find same values in DESCRIPTION column in my database table.
id-------DESCRIPTION
1-------Final
2-------Exam
3-------Test
4-------Test
5-------Mid
6-------Quiz
7-------Quiz
As output it needs to be like:
Final
Exam
Test
Test
Mid
Quiz
Quiz
If a value repating just change them style is enough but i'm really don't know how to do it.
<?php
$check = mysqli_query($connection,"SELECT * FROM EXAMS");
while($test=mysqli_fetch_array($check))
{
echo $test["DESCRIPTION"];
}
?>
Use an EXISTS subquery to look if the same value exists for another id:
$result = $connection->query("
SELECT e.id, e.DESCRIPTION, EXISTS(
SELECT *
FROM EXAMS e2
WHERE e2.DESCRIPTION = e.DESCRIPTION
AND e2.id <> e.id
) as is_duplicate
FROM EXAMS e
ORDER BY e.id
");
Then check in PHP if it is a duplicate (if ($row['is_duplicate'] == 1)) and mark it bold:
while($row = $result->fetch_assoc())
{
if ($row['is_duplicate'] == 1) {
echo "<strong>$row['DESCRIPTION']</strong><br>";
} else {
echo "$row['DESCRIPTION']<br>";
}
}
PHP solution
$result = $connection->query("SELECT * FROM EXAMS");
$data = $result->fetch_all(MYSQLI_ASSOC);
$counts = array_count_values(array_column($data, 'DESCRIPTION'));
foreach($data as $row)
{
if ($counts[$row['DESCRIPTION']] > 1) {
echo "<strong>$row['DESCRIPTION']</strong><br>";
} else {
echo "$row['DESCRIPTION']<br>";
}
}
This question already has answers here:
Select Name instead OF ID in table with ID-Ref Column SQL
(2 answers)
Show Name Instead of ID from Different Table
(2 answers)
Closed 1 year ago.
I have 2 tables
rankID | name
1 | new
2 | learner
3 | experienced
4 | pro
And another with all the user info and passwords and stuff
id | username | rankID
1 | hello | 3
2 | hey | 3
I have come so far so I can display their rank number, but I want to display the rank name. How can I do that? I have tried a lot of things but I'm not so good at sql and the php part of it.
This is the code I use to display the rank number
//Get rankID
$query = "SELECT rankID FROM users WHERE id = '$userId'";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_assoc($result);
$rank = $row['rankID'];
And to display the rank number:
Rank: <?php echo $rank; ?>
Simple JOIN query :-
"SELECT rank.name as rank_name,users.rankID as rankID from users LEFT JOIN rank ON rank.rankID = users.rankID WHERE id = '$userId'"
And then After:-
$query = "SELECT rank.name as rank_name,users.rankID as rankID from users LEFT JOIN rank ON rank.rankID = users.rankID WHERE id = '$userId'";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_assoc($result);
Do:-
$rank = $row['rankID'];
$rank_name = $row['rank_name'];
Rank: <?php echo $rank; ?>
RankName: <?php echo $rank_name; ?>
Or
$rank_data = $row;
Rank: <?php echo $rank_data['rankID']; ?>
RankName: <?php echo $rank_data['rank_name']; ?>
Not:- lot of other possible ways are there which are listed by other programmers in comment and answer as well.
//Get datas
$query = "SELECT rankID, name FROM users WHERE id = '$userId'";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_assoc($result);
$rank = $row['rankID'];
$rank = $row['name'];
And to display the datas:
Rank: <?php echo $rank; ?>
Name: <?php echo $name; ?>
Hope so this should make a trick for you.
$query = "SELECT rankID FROM users WHERE id = '".$userId."'";
$result = $conn->query($query);
$count = $result->num_rows;
if($count==0)
{
return false;
}
else
{
$rows=[];
while($row = $result->fetch_assoc())
{
$rows[] = $row;
}
return $rows;
}
Please use below code
$query = "SELECT name FROM users as u JOIN rank as r ON r.rankID = u.rankID WHERE u.id = '$userId'";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_assoc($result);
$name = $row['name'];
Name: <?php echo $name; ?>
When you want to get data from two different table.You need join query.
Here is your query which will solve your proble definitely :
$q="select a.name,b.rankID from rankname as a INNER JOIN user as b
ON a.rankID = b.rankID";
For more know about How to join two tables see this:http://www.tutorialspoint.com/sql/sql-using-joins.htm
Hope this will help you better.
Please try this
//Get rankID
$query = "SELECT r.name as rank_name FROM rank as r inner join users as u on r.rankID = u.rankID WHERE u.id = '$userId'";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_assoc($result);
$rank = $row['rank_name'];
echo 'Rank: '. $rank;
try this:
//Get rankID
$query = "SELECT rankID, rank.name AS rank_name FROM rank, users WHERE id = '$userId' and users.rankid = rank.rankid";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_assoc($result);
$rank = $row['rank_name'];
echo $rank;
I was working on a post system..
So, I have to show posts by friends of the user and the groups in which user has participated..
Here is my code to show posts..
<?php
$sql = "SELECT * FROM posts WHERE uploader_id=:friend_id ORDER BY id DESC";
$query = $db->prepare($sql);
$query->execute(array(
":friend_id" => $friend_id
));
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$name = $row['name'];
echo "POST BY $name";
}
$sql = "SELECT * FROM group_posts WHERE id=:member_group ORDER BY id DESC";
$query = $db->prepare($sql);
$query->execute(array(
":member_group" => $group_id
));
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$name = $row['name'];
echo "POST BY $name";
}
?>
Now, I want all these posts to be shuffled in a way that all the posts of the post table and group_posts table are shown in the descending order.
UPDATE
I edited my code to this..
I figured out that first I'll have to code this before coding my post system..
<?php
$sql = "SELECT * FROM friends WHERE user_one=:me OR user_two=:me2 UNION SELECT * FROM group_members WHERE member_id=:me3";
$query = $db->prepare($sql);
$query->execute(array(
":me" => $my_id,
":me2" => $my_id,
":me3" => $my_id
));
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$user_one = $row['user_one'];
$user_two = $row['user_two'];
$group_id = $row['group_id'];
if ($user_one == $my_id) {
$friend_id = $user_two;
} else {
$friend_id = $user_one;
}
echo $friend_id . "<BR>" . $group_id;
}
?>
Now, here's the problem..
This is successfully printing the $friend_id but, it shows an undefined index 'group_id' while printing $group_id.
I have checked all the fields are correct.
Try using just one query with UNION
SELECT *
FROM (
SELECT name, id FROM posts WHERE uploader_id=:friend_id
UNION
SELECT name, id FROM group_posts WHERE id=:member_group
) p
ORDER BY p.id DESC
Note, your inner queries must return the same number of columns in the same order (and I think with the same name/alias, too).
I am trying to create a PDO database results page with a previous and next for the previous 10 or next 10 records. I just can't figure out what should go in the 4 ????? areas below. I have tried several different approaches with all sorts of incorrect results. Any ideas on the missing pieces to make this work?
$results = $dbh->prepare("select
stories.SID,
stories.story_name,
stories.category,
stories.genre
FROM stories
WHERE stories.category = :cat OR stories.genre = :gen LIMIT 10");
$results->bindParam(':cat', $scategory, PDO::PARAM_STR);
$results->bindParam(':gen', $sgenre, PDO::PARAM_STR);
$results->execute();
$row = $results->fetchAll(PDO::FETCH_ASSOC);
}
if ($row) {
echo '<table>';
echo '<tr>';
foreach ($row as $all) {
echo '<tr>';
echo "<td>$all[story_name]
</td>";
echo "<td>$all[category]</td>";
echo "<td>$all[genre]</td>";
}
echo '</table>';
}
//get all results from PDO SQL query and pass to previous & next links
$id = $row;
$stmt_a = $pdo->prepare("
(SELECT * FROM stories WHERE ???? ORDER BY id DESC LIMIT 1)
UNION (SELECT * FROM stories WHERE id = (SELECT MAX(id) FROM stories)) LIMIT
1 prev_id");
$stmt_b = $pdo->prepare("
(SELECT * FROM stories WHERE ????? ORDER BY id ASC LIMIT 1)
UNION (SELECT * FROM stories WHERE id = (SELECT MIN(id) FROM stories)) LIMIT
1 next_id");
// $vars = array(':id' => $id);
$prev = $stmt_a->execute();
$next = $stmt_b->execute();
if ($prev) {
while($row = $stmt_a->fetchObject()) {
echo 'Previous';
}
} else {
echo 'no previous';
}
if ($next) {
while($row = $stmt_b->fetchObject()) {
echo 'Next';
}
} else {
echo 'no next';
}
Here is a blog that discusses many aspects of what you are doing:
http://mysql.rjweb.org/doc.php/pagination
It also shows how to do "pagination" in a scalable way.