Left Join After Where Clause - php

I'm having trouble with this query that fetches sorts forum topics on the number of replies in a different table. I tried this with Left join before the where but some data was left out in my while loop.
SELECT forum_topics.*, COUNT(forum_posts.comment_id) AS replies
FROM forum_topics
WHERE forum_topics.subcat_id = '$subcatid'
LEFT JOIN forum_posts
ON forum_topics.topic_id=forum_posts.topic_num
ORDER BY replies DESC
It gives me this as an error:
You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near 'LEFT JOIN forum_posts ON
forum_topics.topic_id=forum_posts.topic_num ORDER BY r' at line 1
This is the query that was working before:
SELECT * FROM forum_topics WHERE subcat_id = '$subcatid' ORDER BY date DESC
To echo I use:
$getChildCategory = mysql_query($query) or die(mysql_error());
$num = mysql_num_rows($get);
if($num == 0){ echo 'No Posts';}
else{
while ($row = mysql_fetch_assoc($get)){
When echoing I only get 1 result with the left join but with the old one I got 2 which is what I expected.

That's because the clauses are in the wrong order.
This is the correct syntax (EDITED per comments below):
SELECT `forum_topics`.*, COUNT(`forum_posts`.`comment_id`) AS `replies`
FROM `forum_topics`
LEFT JOIN `forum_posts`
ON `forum_topics`.`topic_id` = `forum_posts`.`topic_num`
WHERE `forum_topics`.`subcat_id` = '$subcatid'
GROUP BY `forum_posts`.`topic_num`
ORDER BY `replies` DESC
When you perform any sort of JOIN, you create a sort of "virtual table" that is an amalgamation of all tables involved. The where clause operates on this "virtual table", so if you think about it it only makes sense for the WHERE clause to go after this table has been created.

Related

MySQL Inner Join query giving errors

I have two Tables - char_items and items. item_id is a common field among the two tables.
I want read the item_id from 'char_items' table and use that to obtain other information from the 'items' table based on that item_id. But my query is showing up as incorrect in MySQL. Please help --
SELECT * FROM `char_items` WHERE char_id=$char_id && isSlotted=1 INNER JOIN `items` ON char_items.item_id=items.item_id
I keep getting the message:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INNER JOIN `items` ON char_items.item_id=items.item_id
LIMIT 0, 30' at line 1
Joins need to happen before the where clause
SELECT *
FROM char_items c
INNER
JOIN items i
ON c.item_id = i.item_id
WHERE char_id = $char_id
AND isSlotted = 1
where should be after join clause as like below.
SELECT * FROM `char_items` INNER JOIN `items` ON char_items.item_id=items.item_id WHERE char_id=$char_id && isSlotted=1;

mysql limit not work orderby with limit 0,5

$selectorders=sprintf("SELECT s.stud_rollno, s.admissiondate, s.fname, s.lname, s.gender, c.communityname, t.name, y.yearname, s.iname
FROM erp.student s inner join year y
on year_id = s.ayear
inner join community c
on c.d_id = s.community
inner join types t
on t.id = s.department
ORDER BY s.stud_rollno
limit 0,10");
$results = mysql_query($selectorders) or die(mysql_error());
$tot_rsselect = mysql_num_rows($results);
my runtime error is
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIMIT 0, 200' at line 1
but run in localhost/phpmyadmin page.
I think you are trying to select only top 10 rows. So in this scenario there is no need to use 0, 10 or like somthing. You can just simply write LIMIT 10
So your query will be:-
"SELECT s.stud_rollno, s.admissiondate, s.fname, s.lname, s.gender, c.communityname, t.name, y.yearname, s.iname
FROM erp.student s inner join year y
on year_id = s.ayear
inner join community c
on c.d_id = s.community
inner join types t
on t.id = s.department
ORDER BY s.stud_rollno
limit 10";
I'm not sure but this might be your solution.

How do I use MySQL Left Join to get results based on another table row's id?

I am building a custom forum in CodeIgniter. I have four primary tables: parents(categories), children(boards), threads, and messages(replies). The thread table only contains the thread id, author, title, date, and the id of the first message. When a thread is viewed, it takes the column "first_msg_id" to retrieve the content of the thread.
I would like to create a query that gets the count of all the replies in a specific board. Basically, any message that doesn't match a thread's first_msg_id field. Here is what I have so far:
$query = "
SELECT
m.message_id, m.thread_id
t.thread_id, t.first_msg_id
FROM forum_messages AS m
LEFT JOIN forum_threads AS t ON t.first_msg_id != m.message_id
WHERE t.child_id = ".$board_id."
ORDER BY m.message_id";
This is the error I'm getting:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.thread_id, t.first_msg_id FROM forum_messages AS m ' at line 3
Here are my tables:
Update
Ok, so now that I got my query working(well, fixed the error), it's not doing what I want... I think I have my logic wrong. I wrote a script that created 40 new threads in one board. None of them have replies. When I use mysql num rows with the query I made, I get a result of 1560. It should return 0. Why is this happening??? Lol.
Got it working.
You are missing a comma after m.thread_id
Something like
SELECT
m.message_id, m.thread_id,
t.thread_id, t.first_msg_id
FROM forum_messages AS m
LEFT JOIN forum_threads AS t ON t.first_msg_id != m.message_id
WHERE t.child_id = ".$board_id."
ORDER BY m.message_id
Comma missing , after m.thread_id
Try with -
$query = "SELECT m.message_id, m.thread_id, t.thread_id, t.first_msg_id ....
More appropriate -
$query = "
SELECT
m.message_id, m.thread_id,
^
-------------------------|
t.thread_id, t.first_msg_id
FROM forum_messages AS m
LEFT JOIN forum_threads AS t ON t.first_msg_id != m.message_id
WHERE t.child_id = ".$board_id."
ORDER BY m.message_id
";

get count of posts based on count(*)

i am trying to get number of posts that i have
Here is my query
$Query="
SELECT t.*,u.*,c.*
FROM posts as t
LEFT JOIN relations as r on r.post_id = t.post_id
LEFT JOIN users as u on t.auther_id = u.auther_id
LEFT JOIN categories as c on c.cate_id = r.cate_id
GROUP BY t.post_id
";
$Query=mysql_query($Query);
$numberOfPosts=mysql_num_rows($Query);
This query is works very well
but i am trying to convert it, i want make it faster
i want use count(*) instead of t.*
because when i use t.*, it gets the full data of posts and categories
but i want to get count only, So i decided to use count(*) but i don't know how to use it with query like this
Edit
i've replaced SELECT t.*,u.*,c.* with SELECT count(t.*)
But i got mysql Error Warning: mysql_fetch_assoc(): supplied argument
Edit 2:
i am trying SELECT count(t.post_title)
I Got this results
Array ( [count(t.post_id)] => 10 )
But i have only 2 posts!
$Query="
SELECT t.*,u.*,c.*
FROM posts as t
LEFT JOIN relations as r on r.post_id = t.post_id
LEFT JOIN users as u on t.auther_id = u.auther_id
LEFT JOIN categories as c on c.cate_id = r.cate_id
GROUP BY t.post_id
";
$Query=mysql_query($Query);
$numberOfPosts=mysql_num_rows($Query);
Let's take a step back and analyze this query for a moment.
You're selecting everything from three out of four tables used in the query. The joins create some logic to limit what you select to the proper categories, authors, etc. At the end of the day you are getting a lot of data from the database, then in PHP simply asking it how many rows were returned (mysql_num_rows). Instead, what #Dagon is trying to suggest in comments, is that you have MySQL simply count the results, and return that.
Let's refactor your query:
$query = "
SELECT COUNT(t.post_id) AS qty
FROM posts as t
LEFT JOIN relations AS r ON r.post_id = t.post_id
LEFT JOIN users AS u ON t.auther_id = u.auther_id
LEFT JOIN categories AS c ON c.cate_id = r.cate_id
GROUP BY t.post_id
";
$result = mysql_query($query);
$result_row = mysql_fetch_assoc($result);
$numberOfPosts = $result_row['qty'];
(You could also use Barattlo's custom execute_scalar function to make it more readable.)
I would need to see your table structures to be of more help on how to optimize the query and get the desired results.
try doing this:
$Query="
SELECT count(t.*) as count_all
FROM posts as t
LEFT JOIN relations as r on r.post_id = t.post_id
LEFT JOIN users as u on t.auther_id = u.auther_id
LEFT JOIN categories as c on c.cate_id = r.cate_id
GROUP BY t.post_id
";
$Query=mysql_query($Query);
$numberOfPosts=mysql_num_rows($Query);
You want to do
SELECT count(t.id) AS count FROM ....
//do query with PDO or whatever you are using
$rows = mysql_fetch_assoc();
$num_rows = $rows['count'];
You should probably simply use
SELECT count(*) as postingcount FROM posts
Why?
Because you do not have a WHERE clause, so there are no restrictions. Your JOINS do not ADD more rows to the resultset, and in the end your GROUP BY merges every duplicate occurance of a post_id that might have occurred because of joining back into one row. The result should only be counted, so assuming that the real number you want to know is the number of data sets inside the table posts, you do not need any join, and doing count(*) really is a very fast operation on tables in MySQL.
Remember to check if mysql_query returns false, because then you have to check mysql_error() and see why your query has an error.

mysql syntax error on inner join statement

I want to get the 5 last rows from two tables.
Here is the mysql statement I execute:
"SELECT title, thread_id
FROM threads AS t1
JOIN ON comments AS c1 ON t1.user_id = c1.user_id
WHERE t1.user_id=".$userID
." OR c1.user_id=".$userID.
" ORDER BY thread_id DESC
LIMIT 0,5"
Here is the mistake:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ON comments AS c1 ON t1.user_id = c1.user_id WHERE t1.user_id=1 OR c1.' at line 3
What am I doing wrong?!?
You have a superfluous ON before comments.
There isnt anything like JOIN ON should be just JOIN or INNER JOIN, LEFT JOIN. something like this:
"SELECT title, thread_id
FROM threads AS t1
JOIN comments AS c1 ON t1.user_id = c1.user_id
WHERE t1.user_id=".$userID
." OR c1.user_id=".$userID.
" ORDER BY thread_id DESC
LIMIT 0,5"
Remove the extra ON in 3rd line. It will works.
"SELECT title, thread_id
FROM threads AS t1
JOIN comments AS c1 ON t1.user_id = c1.user_id
WHERE t1.user_id=".$userID
." OR c1.user_id=".$userID.
" ORDER BY thread_id DESC
LIMIT 0,5"

Categories