Query Issue - Trying to group comments within a discussion - php

I've spent the last few days wrestling with a MYSQL query issue. I hope someone can point me in the right direction.
I'm querying two tables ('questions' and 'comments') with the goal of returning the following layout:
Question 1
Comment 1
Comment 2
Comment 3
Question 2
Comment 4
Comment 5
And so on...
Comments are unique to a question (i.e. comments live under a parent question).
My query (which I know is incorrect) looks like this:
<?php
$query = "SELECT discussion.*, comments.* FROM discussion LEFT JOIN comments ON discussion.referenceID = comments.commentID";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
echo $row['question']. " - ". $row['comment']. "<br /><br />";
}
?>
The result:
Question 1 - Comment 1
Question 1 - Comment 3
Question 2 - Comment 2
I'm close, but can't achieve the multiple comments under the single question. I tried a 'GROUP BY discussion.question' but that limited my results to:
Question 1 - Comment 1
Question 2 - Comment 2
To put it in context I'm trying to allow users to submit comments on multiple questions displayed on a single page.
Thanks in advance.
RR

try this:
$query = "SELECT *
FROM discussion, comments
WHERE discussion.referenceID = comments.commentID
GROUP BY discussion.referenceID;

Just store the previous question and compare it to the current.
Sketch:
$prev_question = null;
while($row = mysql_fetch_array($result)) {
if ($prev_question != $row['question']) {
echo '<b>' . $row['question'] . '<b><br />';
$prev_question = $row['question'];
}
echo $row['comment'] . '<br />';
}

Zerkms, brilliant! Thanks for the response. Works perfectly, aside from one issue.
The questions only appear if there is a comment associated (an issue I caused myself, at some point). The goal is to display all comments regardless of if comments are assigned.
Working code:
<?php
$query = "SELECT discussion.*, comments.* FROM discussion LEFT JOIN comments ON discussion.referenceID = comments.commentID";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
$prev_question = null;
while($row = mysql_fetch_array($result)) {
if ($prev_question != $row['question']) {
echo "<h3>" . $row['question'] . "</h3>";
$prev_question = $row['question'];
}
echo "<img src=\"images/bg_addform_topFull.gif\" width=\"446\" height=\"11\" /><div class=\"comment\"><h3>" . $row['author'] . "</h3><div class=\"greyText\">" . $row['dt'] . "</div><p>" . $row['comment'] . "</p></div><img src=\"images/bg_addform_bottom.gif\" width=\"446\" height=\"11\" class=\"footerImage\" />";
}
}
?>
Again, thanks for the help.

Related

Is it possible to wrap looping PHP output in tags?

everyone. I'm having a bit of a PHP conundrum here and I couldn't find a good answer that already existed. You see, I'm working on a project where I have to take a classmate's discography website and revamp it with PHP, to where, instead of having the album covers and tracklists hard-coded in, it would query the database for them. My problem is that I have to keep the general style of his site intact, and I'm having trouble doing that. Basically his styles depend on having the album cover, name, and tracklists in div tags, and the style he's got in place is achieved through both Bootstrap and his own, custom CSS stylesheet.
Before I start to ramble, my question is: is there any way to wrap looping output in HTML tags? I need to get the album cover, album name, and tracklists in a div tag, but only the tracklists loop. Here is the code I have in place to query the database:
<?php
require ('mysqli_connect.php');
// Connect to database server
mysql_connect("localhost", "admin", "instructor") or die(mysql_error());
// Select database
mysql_select_db("phprediscography") or die(mysql_error());
// SQL query
$q = "SELECT DISTINCT albums.albumname, albums.albumID, albums.coverart
FROM albums
JOIN tracks
ON albums.albumID=tracks.albumID"; //select UNIQUE results from database
$t = "SELECT trackname FROM tracks WHERE albumID = 1";
$b = "SELECT trackname FROM tracks WHERE albumID = 2";
$n = "SELECT trackname FROM tracks WHERE albumID = 3";
$r = "SELECT trackname FROM tracks WHERE albumID = 4";
$result = mysqli_query($dbcon, $q);
$result1 = mysqli_query($dbcon, $t);
$result2 = mysqli_query($dbcon, $b);
$result3 = mysqli_query($dbcon, $n);
$result4 = mysqli_query($dbcon, $r);
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) { //loop through database to get each album
echo '<img class="img-responsive" src=' . $row['coverart'] . '>' . '<br />';
echo '<h2>' . $row['albumname'] . "</h2><br />";
if ($row['albumID'] == 1) {
foreach($result1 as $row1) { //loop through tracks and output to page
echo '<p>' . $row1['trackname'] . '</p>';
}
}
if ($row['albumID'] == 2) {
foreach($result2 as $row2) { //loop through tracks and output to page
echo '<p>' . $row2['trackname'] . '</p>';
}
}
if ($row['albumID'] == 3) {
foreach($result3 as $row3) { //loop through tracks and output to page
echo '<p>' . $row3['trackname'] . '</p>';
}
}
if ($row['albumID'] == 4) {
foreach($result4 as $row4) { //loop through tracks and output to page
echo '<p>' . $row4['trackname'] . '</p>';
}
}
}
// Close the database connection
mysql_close();
?>
If I need to post anything else, let me know, this is my first-ever question so I'm just kind of feeling it out.
By doing your $t = "SELECT trackname FROM tracks WHERE albumID = #"; and if($row['albumID']==#) you are essentially still hardcoding similar to your friend. Just do 1 query, where you join all the tracks. Then when looping, group by the albumname -
<?php
require('mysqli_connect.php');
// SQL query
$q = "SELECT albums.albumname, albums.albumID, albums.coverart, tracks.trackname
FROM albums
JOIN tracks
ON albums.albumID=tracks.albumID";
$result = mysqli_query($dbcon, $q);
$current_albumID = ""; //create current albumID var to be used below.
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)){//loop through database to get each album
if($row['albumID'] != $current_albumID){
echo '<img class="img-responsive" src='.$row['coverart'] . '>' . '<br />';
echo '<h2>' . $row['albumname'] . "</h2><br />";
$current_albumID = $row['albumID']; // set current albumID to this albumID
}
echo '<p>' . $row['trackname'] . '</p>';
}
?>
Try something like this instead: Get all the data you're after in your first query, then use php to process that into your output:
$q = "SELECT albums.albumname, albums.albumID, albums.coverart, tracks.trackname
FROM albums
JOIN tracks ON albums.albumID=tracks.albumID";
$result = mysqli_query($dbcon, $q);
$lastAlbumId = null;
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)){
if ($lastAlbumId != $row['albumID']) {
echo '<img class="img-responsive" src="'.htmlentities($row['coverart']).'"><br />';
echo '<h2>'.htmlentities($row['albumname']).'</h2><br />';
}
echo '<p>'.htmlentities($trackname).'</p>';
$lastAlbumId = $row['albumID'];
}
A few things to note:
I added use of htmlentities to escape the user data so malicious people can't type in HTML somewhere and have it appear on your site. This is something you should do almost everywhere you're displaying data from a database in a html site, except for very rare cases where you know what you're doing.
You probably don't need those <br /> tags - <h2> is a block level element so it'll force itself onto it's own line anyway (unless there's some silly CSS rules somewhere).
Also note - the above code is untested - typed straight into browser. There may be some syntax errors - let me know if you see any problem and I'll happily edit the answer. (or you can suggest an edit).

How to make a style list out of database information

I realize this isn't the typical question, and I will delete it tonight as to not take up space with a non-code error question, but I really need some help. I am trying to pull information from the question database and create a list of questions organized by the question title. When the user click on the question title, it brings them to the next page according to the question_id.
I posted the code for how the list of questions are currently being displayed, but I can't figure out how I would style them to make it actually look appealing. Would I use say 10 div tags with 10 different id's that all specify the background, and distance from the top? or would I use a table? or is there something else I could use?
I'm new with php and html, and I really don't know many ways to display information that is being pulled from the database....
Current_questions.php
<?php
$i = 0;
$str = "";
$sql = "SELECT * FROM questions";
$result = mysql_query ($sql, $conn) or die(mysql_error());
if (mysql_num_rows($result) >= 0)
{
while ($row = mysql_fetch_array($result, MYSQL_ASSOC) and $i<10 )
{
$i++;
$str .= $i . ". ";
$str .= "<a href='show_question2.php?question_id=" . $row["question_id"] . "'>"
. $row["title"] . "</a> <br> ";
}
print $str;
}
?>
This code currently just prints a list of the title's, and that is not ideal. Thanks!
im not looking for how to code it, just suggestion on best way. Simple answer of a couple of words is all i am looking for –
It really helps to learn some CSS
$toggle = false;
while ($row = mysql_fetch_array($result, MYSQL_ASSOC) and $i<10 )
{
$i++;
$str .= $i . ". ";
$toggle = !$toggle;
if($toggle)
$style = "background: Grey;";
else
$style = "background: White;";
$str .= "<a style='padding: 10px;$style' href='show_question2.php?question_id=" . $row["question_id"] . "'>"
. $row["title"] . "</a> <br> ";
}
Start with the HTML entity which best describes what you are doing. To me that sounds like a list. Now decide if it is an ordered or unordered list. If unsure go with u-ordered
You'll probably want your html to end up something like:
<ul>
<li><a href='show_question2.php?question_id=1'>Question 1 Title</a></li>
<li><a href='show_question2.php?question_id=2'>Question 2 Title</a></li>
<li><a href='show_question2.php?question_id=3'>Question 3 Title</a></li>
</ul>
Now look around the internet for one of the many articles on styling a list.
Here are 3 to start you off:
http://www.alistapart.com/articles/taminglists/ -- I'm a big fan of these guys
http://www.webreference.com/programming/css_style2/index.html
http://www.marcofolio.net/css/8_different_ways_to_beautifully_style_your_lists.html
A real quick and dirty examples with lists

Sorting PHP echo output by time posted

Ok, so. I have asked about 5 questions on stackOverflow today, you've all been so helpful.
Now, i'm a designer, learning to code, so bear with me.
I have a mySQL table, with a small CMS/Blog im building.
I have it styled how I want to now.
This is the code for the page.
$result = mysql_query("SELECT * FROM Blog");
while($row = mysql_fetch_array($result))
{
echo "<h1>" . $row['Title'] . "</h1>";
echo "<br>";
echo "<h2>" . "Posted on: " . $row['Date'] . "</h2>";
echo "<br>";
echo "<img src='".$row['Image']."'/>";
echo "<br>";
echo $row['Message'];
echo "<br>";
echo "<br>";
}
I'm still working on it so its all good.
What I want to know is, this code is outputting my sql data into a page. Is there any way of telling the page what order to echo the data, for instance. in my SQL table i have:
2012-11-03 16:16:06 This is my First Blog Post This is the first message of the first blog post. ... http://blog.gettyimages.com/wp-content/uploads/201.
and next is
2012-11-03 16:17:29 This is my Second Blog Post This is the second message of the Second Post, You... http://www.aviation-images.com/user/zooms/118/451n...
How can i tell the page to Always display the most recent post at the top, and older ones below.?
Use order by in your query:
$result = mysql_query("SELECT * FROM Blog ORDER BY Date DESC");
If your MySQL database schema uses DATETIME for the Date column, you can simply sort in the MySQL query with ORDER BY:
$result = mysql_query("SELECT * FROM Blog ORDER BY Date DESC");
If you have an auto-increment column like post_id, then you can use ORDER BY post_id DESC as well. :)

While loop and for statement

I am trying to build an online reading test for my students. I currently have two tables in my database : 'student' and 'questions'. In 'student', I have a row for each student which containts it's name, group number and answers to the questions. Questions cols are called question[1], question [2], and so on.
In 'questions', I have 4 cols : ID, 'first', 'chapter' and 'question'. 'first' is a true/false field, if it is the first question to a chapter its value is 1. I call those with a while loop.
echo '<ol>';
$query = mysql_query("SELECT * FROM `question`");
while($row_q = mysql_fetch_assoc($query)) {
if($row_q['first']==1){
echo '<h2>Chapter '.$row_q['chapter'].'</h2><br>';
}
echo '<li>';
echo $row_q['question'];
echo '</li>';
echo '<br>';
}
echo '</ol>';
It echoes beautifuly. Now, I'm trying to put an input field under each question so the student can give an answer and submit it at the end of the page. How can I do this? I tried using a for($i=1;$i<=10;$i++) statement since I want each field to be named with a different number, but no matter where I insert it, I either end up with a bunch of identical fields next to each other or my questions echoed over and over again.
I'm open to all suggestions. Thanks!
there's no need to do a for loop, you're already in a loop :) just set a variable called question number and increment it in the while loop.
$question_number =1;
echo '<ol>';
$query = mysql_query("SELECT * FROM `question`");
while($row_q = mysql_fetch_assoc($query)) {
if($row_q['first']==1){
echo '<h2>Chapter '.$row_q['chapter'].'</h2><br>';
}
echo '<li>';
echo "<label>$question_number".$row_q['question']."</label>";
echo "<input type='text' name='$row_q[\'ID\']'></input>";
echo '</li>';
echo '<br>';
$question_number++;
}
echo '</ol>';
echo '<input name="answer[' . htmlspecialchars($row_q['ID']) . ']" type="text" value="" />';
under the question text... Then in PHP var_dump($_REQUEST) to see the answers...
EDIT:
For displaying the saved answer, you'll want to do something like this:
echo '<input name="answer_' . $idx . '" type="text" ' .
value="' . htmlspecialchars($student_row["answer_$idx"]) . '" />';
and maintain a counter $idx as you loop...
That's if your answer are laid out flat in the student table per your description and the answer value columns are named "answer_1" etc.
If the answers are normalized in a separate table, you can join the tables together:
select * from question q left join answer a on a.question_id = q.question_id and
a.student_id = <current student id>

Pulling a survey with multiple answers from a database

I have a working survey that pulls each question and any related answers from multiple tables. Each question is stored in the following table:
tblQuestions, with the fields:
qID
qText.
The related answers are stored in the table:
tblPossAnswers, with the fields:
aID
qID
answerText.
So, I would have 3 possible answers for each question. My sql to pull everything is:
select * from tblQuestions, tblPossAnswers where
tblPossAnswers.qID = tblQuestions.qID
order by tblQuestions.qID ASC
And my PHP to display it:
while ($row = mysql_fetch_array($result)) {
echo "<p>" . $row['qText'] . "</p><br />";
echo "<input type='radio' name='".$row['qID']."' value='".$row['aID']."' />";
echo $row['answerText'];
}
The problem is this is displaying the qText every time it displays a possible answer. So it looks like:
Question 1
Possible answer 1
Question 1
Possible answer 2
Question 1
Possible answer 3
Question 2
Possible answer 1
Question 2
Possible answer 2
Question 2
Possible answer 3
What I would like to do is have the qText only display when the first possible answer is pulled. I'm still somewhat of a newb to MySQL, so the solution might be something very simple that I'm just not seeing.
You can either test for whether the question has changed within your PHP loop:
while ($row = mysql_fetch_array($result)) {
if ($row['qID'] != $lastQuestionID) {
echo "<p>" . $row['qText'] . "</p><br />";
$lastQuestionID = $row['qID'];
}
echo "<input type='radio' name='".$row['qID']."' value='".$row['aID']."' />";
echo $row['answerText'];
}
Or else you can group the MySQL results by question using GROUP_CONCAT, specifying a separator on which you then split the answers in PHP:
select *, group_concat(answerText separator char(30)) as answers
from tblQuestions join tblPossAnswers using (qID)
group by tblQuestions.qID
order by tblQuestions.qID ASC
Then:
while ($row = mysql_fetch_array($result)) {
echo "<p>" . $row['qText'] . "</p><br />";
foreach (explode(chr(30), $row['answers']) as $answer) {
echo "<input type='radio' name='".$row['qID']."' value='".$answer."' />";
echo $answer;
}
}
No need to change anything in sql just change php slightly as following
while ($row = mysql_fetch_array($result)) {
if ($row['qText'] != $lastQuestion) {
echo "<p>" . $row['qText'] . "</p><br />";
$lastQuestion = $row['qText'];
}
echo "<input type='radio' name='".$row['qID']."' value='".$row['aID']."' />".$row['answerText'];
}

Categories