How to select comments with child comments from MySQL? - php

I have two tables:
'comments'
| id | content | user_id | article_id | parent_id |
'users'
| id | name | photo |
And my queries are:
<?php
$query = mysql_query("SELECT comments.id, comments.content, users.name,
users.photo FROM comments, users WHERE comments.article_id = '".$get_id."'
AND comments.parent_id = 0 AND comments.user_id = users.id");
while($res = mysql_fetch_assoc($query))
{
$id = $res['id'];
$content = $res['content'];
$name = $res['name'];
$photo = $res['photo'];
echo $photo;
echo $name;
echo $content;
$query2 = mysql_query("SELECT comments.id, comments.content, users.name,
users.photo FROM comments, users WHERE comments.article_id = '".$get_id."'
AND comments.parent_id = '".$id."' AND comments.user_id = users.id");
while($res2 = mysql_fetch_assoc($query2))
{
$id2 = $res2['id'];
$content2 = $res2['content'];
$name2 = $res2['name'];
$photo2 = $res2['photo'];
echo $photo2;
echo $name2;
echo $content2;
}
}
?>
It doesn't work properly. It shows 1 parent and 1 child comment in each nest although there are several child comments.
How can I fix and minimize it? Can it be done by using only one query?
Thank you!

JOIN the table on itself.
Change your query to:
SELECT comments.id, comments.content, users.name,
users.photo FROM comments JOIN users ON comments.user_id = users.id JOIN
comments c ON comments.id =
c.parent_id WHERE
comments.article_id = '".$get_id."'
AND comments.parent_id = '".$id."'
You don't need the second query, here's the full code:
<?php
$query = mysql_query("SELECT comments.id, comments.content, users.name,
users.photo FROM comments JOIN users ON comments.user_id = users.id JOIN
comments c ON comments.id =
c.parent_id WHERE
comments.article_id = '".$get_id."'");
while($res = mysql_fetch_assoc($query))
{
$id = $res['id'];
$content = $res['content'];
$name = $res['name'];
$photo = $res['photo'];
echo $photo;
echo $name;
echo $content;
}
?>

Just use a JOIN to fetch the comments and with all the children.
SELECT users.id userID, users.name, users.photo , childrenComments.*,
parentComments.id cpId, parentComments.content cpContent,
parentComments.user_id cpUser_id,parentComments.article_id cpArticleId
FROM users JOIN (SELECT * FROM Comment WHERE id=0) parentComments
ON users.id=parentComments.user_id LEFT JOIN Comment childrenComments
ON parentComments.id=childrenComments.parent_id;
Then you can the loop through the result to print it appropriately. This would be better as you would have to run just a single query.

Related

Three SELECT and two jsons

I created a SELECT to get my communities.
And create two SELECTs to get the communities I'm following.
But I get just my communities.
I do not get the communities I'm following.
$user_id = $_GET["id"];
$row1 = array();
$row2 = array();
// get my communities
$res1 = mysql_query("SELECT * FROM communities where user_id = '$user_id'");
while($r1 = mysql_fetch_assoc($res1)) {
$row1[] = $r1;
}
// get "id" of my communities I'm following
$res = mysql_query("SELECT * FROM communities_follow where user_id = '$user_id'");
while($r = mysql_fetch_assoc($res)) {
$coid = $r["coid"];
// get my communities I'm following
$res2 = mysql_query("SELECT * FROM communities where id = '$coid'");
while($r2 = mysql_fetch_assoc($res2)) {
$row2[] = $r2;
}
}
$resp = array_replace_recursive($row1, $row2);
print json_encode( $resp );
The inner join will get you those communities only, where you are following:
SELECT c.* FROM communities c
INNER JOIN communities_follow cf ON c.id = cf.coid
WHERE cf.user_id = '$user_id';
Or, without a JOIN:
SELECT * FROM communities
WHERE EXISTS (SELECT 1 FROM communities_follow cf
WHERE c.id = cf.coid AND cf.user_id = '$user_id')
Try this sql.
SELECT * FROM communities c LEFT JOIN communities_follow cf ON c.user_id = cf.user_id where
cf.user_id = '$user_id';

Get Results of a search form- MySQL PHP

I have a joined table and it gives all books of my database. And all books are displaying properly. But I need to work it according to search queries entered in form.
this is my query for join.
$rs = mysqli_query($connection,"SELECT DISTINCT bk.title As Title, YEAR(bk.date_released) AS Year, bk.price AS Price, cat.name AS Category, pub.name AS Publisher, aut.name AS Author,co.name AS Cover, cp.count AS Copies
FROM books bk
JOIN (SELECT book_id, COUNT(*) as count FROM copies GROUP BY book_id) cp
ON bk.id = cp.book_id
JOIN category cat
ON cat.id = bk.category_id
JOIN publishers pub
ON pub.id = bk.publisher_id
JOIN books_covers bk_co
ON bk_co.book_id = bk.id
JOIN covers co
ON co.id = bk_co.cover_id
JOIN books_authors bk_aut
ON bk_aut.book_id = bk.id
JOIN authors aut
ON aut.id = bk_aut.author_id
JOIN books_languages bk_lan
ON bk_lan.book_id = bk.id
JOIN languages lan
ON lan.id = bk_lan.lang_id
JOIN books_locations bk_loc
ON bk_loc.book_id = bk.id
JOIN locations loc
ON loc.id = bk_loc.location_id
ORDER BY bk.title ASC
");
$copies = mysqli_query($connection,"SELECT DISTINCT COUNT(copies.book_id) FROM copies INNER JOIN books ON copies.book_id=books.id
");
$dup = mysqli_query($connection,"SELECT book_id, COUNT(*) as count FROM copies GROUP BY book_id");
$rows_copies = mysqli_fetch_array($copies);
$rows = mysqli_fetch_assoc($rs);
$tot_rows = mysqli_num_rows($rs);
And this is my variables of search form
if(!empty($_GET)){
$title = $_GET['title'];
$author = $_GET['author'];
$isbn = $_GET['isbn'];
$language = $_GET['language'];
$publisher = $_GET['publisher'];
$year = $_GET['year'];
$category = $_GET['category'];
}else{
$title = "";
$author = "";
$isbn = "";
$language = "";
$publisher = "";
$year = "";
$category = "";
$language = "";
}
And this is my code for displaying results,
<div class="jumbo">
<?php if($tot_rows > 0){ ?>
<?php do { ?>
<div class="col-md-3">
<span class="product-image">
<img src="<?php echo $rows['Cover'] ?>" class="img-thumbnail product-img" alt="">
</span>
<ul class="iteminfo">
<li><strong>Title: </strong><?php echo $rows['Title'] ?></li>
<li><strong>Category: </strong><?php echo $rows['Category'] ?></li>
<li><strong>Author: </strong><?php echo $rows['Author'] ?></li>
<li><strong>Price: </strong><?php echo $rows['Price']." Rs" ?></li>
<li><strong>Publisher: </strong><?php echo $rows['Publisher'] ?></li>
<li><strong>Copies: </strong><?php echo $rows['Copies'] ?></li>
</ul>
</div>
<?php } while($rows=mysqli_fetch_assoc($rs)); }else{ ?>
<?php echo 'No Results'; }?>
</div>
How I get results only I searched with corresponding search queries. For an example if I search a book called "Romeo Juliet" I need to display that book only
I tried to test the diplay with this code and never succeed
$titlequery = mysqli_query($connection," SELECT * FROM "$rs" WHERE Title = "$title" ");
$rows = mysqli_fetch_assoc($titlequery);
Help me to solve this.
You're trying to execute a subquery, but the $rs variable you are passing in is a resource, not a string. If you set the original query to a variable and pass that in, then it should work:
$sql = "SELECT DISTINCT bk.title As Title, YEAR(bk.date_released) AS Year, bk.price AS Price, cat.name AS Category, pub.name AS Publisher, aut.name AS Author,co.name AS Cover, cp.count AS Copies
FROM books bk
JOIN (SELECT book_id, COUNT(*) as count FROM copies GROUP BY book_id) cp
ON bk.id = cp.book_id
JOIN category cat
ON cat.id = bk.category_id
JOIN publishers pub
ON pub.id = bk.publisher_id
JOIN books_covers bk_co
ON bk_co.book_id = bk.id
JOIN covers co
ON co.id = bk_co.cover_id
JOIN books_authors bk_aut
ON bk_aut.book_id = bk.id
JOIN authors aut
ON aut.id = bk_aut.author_id
JOIN books_languages bk_lan
ON bk_lan.book_id = bk.id
JOIN languages lan
ON lan.id = bk_lan.lang_id
JOIN books_locations bk_loc
ON bk_loc.book_id = bk.id
JOIN locations loc
ON loc.id = bk_loc.location_id
ORDER BY bk.title ASC
";
$rs = mysqli_query($connection, $query);
$titlequery = mysqli_query($connection, " SELECT * FROM ({$query}) WHERE Title = '{$title}'");
Also, watch your quotation marks in SQL queries when you need to use PHP quotation marks as string delimiters. PHP will interpret your string of " SELECT * FROM "$rs" WHERE Title = "$title" " as SELECT * FROM, the $rs resource, WHERE Title =, the $title variable, and , but without any concatenation. You'd need to backslash your SQL quotations, like " SELECT * FROM \"$rs\" WHERE Title = \"$title\" ", so PHP doesn't think you want to end your string.

Sort the results of a query using results of another query

Im working on a message board of some sort and i have everything up an running except one little part, the threads need to be sorted by the date/time of the latest post in them (standard forum format), which im having lots of trouble wrapping my head around.
This is the querys im using, i know its not pretty and its not safe, i will be reworking them once i learn how to do it properly.
$sql = "SELECT Thread_ID, Thread_Title, Board_ID, Author FROM threads WHERE Board_ID='$Board_ID' LIMIT $offset, $rowsperpage";
$result = mysql_query($sql, $conn) or trigger_error("SQL", E_USER_ERROR);
while ($row = mysql_fetch_assoc($result))
{
$Thread_ID = $row['Thread_ID'];
$Thread_Title = $row['Thread_Title'];
$Board_ID = $row['Board_ID'];
$Author = $row['Author'];
$getauthor = mysql_query("SELECT * FROM members WHERE Member_ID='$Author'");
while ($row = mysql_fetch_assoc($getauthor))
{
$Post_Author = $row['Post_As']; }
$postcount = mysql_query("SELECT Post_ID FROM posts WHERE Thread_ID='$Thread_ID'");
$Posts = mysql_num_rows($postcount);
$getlatest = mysql_query("SELECT * FROM posts WHERE Thread_ID='$Thread_ID' ORDER by Post_DateTime DESC LIMIT 1");
while ($row = mysql_fetch_assoc($getlatest))
{
$Post_DateTime = time_ago($row['Post_DateTime']);
$Member_ID = $row['Member_ID']; }
$getmember = mysql_query("SELECT * FROM members WHERE Member_ID='$Member_ID'");
while ($row = mysql_fetch_assoc($getmember))
{
$Post_As = $row['Post_As']; }
So what im trying to do is Sort $sql by $getlatest, i tried adding another query above $sql that did basically the same as $getlatest and then had $sql order by that but alas it just broke everything.
I know i have to make a variable to sort the $sql by but its that variable thats driving me mad.
any help would be appreciated, thanks.
current error message as requested:
Fatal error: SQL - Unknown column 'posts2.LatestPost' in 'on clause' - SELECT threads.Thread_ID, threads.Thread_Title, threads.Board_ID, threads.Author, Sub1.LatestPost, Sub1.PostCount, members.Post_As, members2.Member_ID AS LastPostMemberID, members2.Post_As AS LastPostMemberPostAs FROM threads INNER JOIN (SELECT Thread_ID, MAX(posts.Post_DateTime) AS LatestPost, COUNT(*) AS PostCount FROM posts GROUP BY Thread_ID) Sub1 ON threads.Thread_ID = Sub1.Thread_ID INNER JOIN members ON threads.Author = members.Member_ID INNER JOIN posts posts2 ON posts2.Thread_ID = Sub1.Thread_ID AND posts2.LatestPost INNER JOIN members members2 ON members2.Member_ID = posts2.Member_ID WHERE threads.Board_ID='1' ORDER BY Sub1.LatestPost DESC LIMIT 0, 25 in C:\wamp\www\forum\include\threads.php on line 86
You should be able to do it using something like this for your first query:-
$sql = "SELECT threads.Thread_ID, threads.Thread_Title, threads.Board_ID, threads.Author, MAX(posts.Post_DateTime) AS LatestPost
FROM threads
LEFT OUTER JOIN posts ON threads.Thread_ID = posts.Thread_ID
WHERE threads.Board_ID='$Board_ID'
GROUP BY SELECT threads.Thread_ID, threads.Thread_Title, threads.Board_ID, threads.Author
ORDER BY LatestPost DESC
LIMIT $offset, $rowsperpage";
EDIT
Not tested the following but looking at your selects I think you could probably put it together into a single SELECT. Something like this:-
$sql = "SELECT threads.Thread_ID, threads.Thread_Title, threads.Board_ID, threads.Author, Sub1.LatestPost, Sub1.PostCount, members.Post_As, members2.Member_ID AS LastPostMemberID, members2.Post_As AS LastPostMemberPostAs
FROM threads
INNER JOIN (SELECT Thread_ID, MAX(posts.Post_DateTime) AS LatestPost, COUNT(*) AS PostCount FROM posts GROUP BY Thread_ID) Sub1
ON threads.Thread_ID = Sub1.Thread_ID
INNER JOIN members
ON threads.Author = members.Member_ID
INNER JOIN posts posts2
ON posts2.Thread_ID = Sub1.Thread_ID AND posts2.Post_DateTime = Sub1.LatestPost
INNER JOIN members members2
ON members2.Member_ID = posts2.Member_ID
WHERE threads.Board_ID='$Board_ID'
ORDER BY Sub1.LatestPost DESC
LIMIT $offset, $rowsperpage";
$result = mysql_query($sql, $conn) or trigger_error("SQL", E_USER_ERROR);
while ($row = mysql_fetch_assoc($result))
{
$Thread_ID = $row['Thread_ID'];
$Thread_Title = $row['Thread_Title'];
$Board_ID = $row['Board_ID'];
$Author = $row['Author'];
$Post_Author = $row['Post_As'];
$Posts = $row['PostCount'];
$Post_DateTime = time_ago($row['LatestPost']);
$Member_ID = $row['LastPostMemberID'];
$Post_As = $row['LastPostMemberPostAs'];

Select same column name from two tables

I have this query:
$result3 = mysql_query("SELECT posts.id, posts.date, posts.title, comments.post, comments.id, comments.date FROM posts, comments WHERE posts.id = comments.post")
or die(mysql_error());
while($row2 = mysql_fetch_array( $result3 )) {
echo $row2['title'];
}
The problem is with the posts.id , posts.date and comments.id , comments.date . How can I get out id, date for both tables $row2['....]; I tried $row2['posts.id']; but it didn't work!
Name the column in your query (this is called an column alias) like this:
SELECT
posts.id as postsID,
posts.date,
posts.title,
comments.post,
comments.id as CommentsID,
comments.date
FROM
jaut_posts,
f1_comments
WHERE
jaut_posts.id = f1_comments.post
Then you can use:
echo $row2['postsID'];
echo $row2['commentsID'];
Edit:
You may also benefit from this question I wrote and answered which discusses many common SQL queries and requests.
Use the as in your query, some thing like
select post.id as PostId, comment.id as CommentId
and then :
row["PostId"]
row["CommentId"]
while($row2 = mysql_fetch_array( $result3 )) {
$post_id = $row2[0];
$posts_date = $row2[1];
$posts_title = $row2[2];
$comments_post = $row2[3];
$comments_id = $row2[4];
$comments_date = $row2[5];
}
change
SELECT posts.id, posts.date, posts.title, comments.post, comments.id, comments.date
into
SELECT posts.id AS postsid, posts.date, posts.title, comments.post, comments.id AS commentsid, comments.date
then you can use $row2['postsid']; and $row2['commentsid'];
Create alias:
$sql = 'SELECT posts.id AS post_id, comments.id AS comment_id ...';
$row = mysql_fetch_assoc($sql);
echo $row['post_id'];
echo $row['comment_id'];
or, alternatively, you can access it by indexes (since you're using mysql_fetch_array anyway)
echo $row[0]; // posts.id

PHP MySQL query help

I am trying to use this query to return every instance where the variable $d['userID'] is equal to the User ID in a separate table, and then echo the username tied to that user ID.
Here's what I have so far:
$uid = $d['userID'];
$result = mysql_query("SELECT u.username
FROM users u
LEFT JOIN comments c
ON c.userID = u.id
WHERE u.id = $uid;")$row = mysql_fetch_assoc($result);
echo $row['username'];
This should work
$uid = mysql_real_escape_string($d['userID']);
$result = mysql_query("SELECT u.username
FROM users u
LEFT JOIN
comments c
ON c.userID = u.id
WHERE u.id = '$uid'");
while($row = mysql_fetch_assoc($result))
{
//PRINTS ALL INSTANCES OF THE ROW
echo $row['username'];
}
what is printed from the echo above.
if you're looking to get all the results. wrap your mysql_fetch_assoc in a while loop:
$result = mysql_query("SELECT u.username
FROM users u
LEFT JOIN comments c
ON c.userID = u.id
WHERE u.id = $uid;");
while($row = mysql_fetch_assoc($result)){
echo $row['username'];
}
Try this:
$uid = $d['userID'];
$result = mysql_query("SELECT u.username
FROM users u
LEFT JOIN comments c
ON c.userID = u.id
WHERE u.id = $uid");
while($row = mysql_fetch_assoc($result))
{
echo $row['username'];
}
*EDIT:*Removed semicolon.

Categories