I have two tables:
cc_videos with fields: id, challenge_id, upload_date, owner_id
cc_video_votes with fields id, video_id, vote_date
Field "id" in "cc_videos" corresponds to a field "video_id" in "cc_video_votes" and I have a statement like this:
SELECT cc_videos.*, COUNT(video_id) AS votes_count
FROM cc_videos LEFT JOIN cc_video_votes
ON cc_videos.id = cc_video_votes.video_id
GROUP BY cc_videos.id
ORDER BY votes_count desc
Now this works OK - lists ALL VIDEOS sorted by videos with highest vote rate first. Now i want to put condition to list only videos from "cc_videos" WHERE challenge_id matches variable "$challenge_id", but when I put condition like this it returns 0 results:
SELECT cc_videos.*, COUNT(video_id) AS votes_count
FROM cc_videos WHERE challenge_id = "$challenge_id"
LEFT JOIN cc_video_votes
ON cc_videos.id = cc_video_votes.video_id
GROUP BY cc_videos.id
ORDER BY votes_count desc
Am I using WHERE clause correctly ?
No you are not.
SELECT cc_videos.*, COUNT(video_id) AS votes_count
FROM cc_videos
LEFT JOIN cc_video_votes
ON cc_videos.id = cc_video_votes.video_id
WHERE cc_videos.challenge_id = "$challenge_id"
GROUP BY cc_videos.id
ORDER BY votes_count desc
WHERE syntax should stay in clauses, check documentation here
Change your query to:
SELECT cc_videos.*,
Count(video_id) AS votes_count
FROM cc_videos
LEFT JOIN cc_video_votes
ON cc_videos.id = cc_video_votes.video_id
WHERE cc_videos.challenge_id = "$challenge_id"
GROUP BY cc_videos.id
ORDER BY votes_count DESC
Related
I have a query that LEFT JOINS another table to group rows. I am trying to only select records from the first table "googleimage" where the user_id is a certain number. (user_id is a column in "googleimage" table.
SELECT g.*
FROM googleimage g
LEFT JOIN (SELECT image_id, COUNT(*) AS cnt
FROM googleimagefound WHERE status = 0
GROUP BY image_id) gf ON gf.image_id = g.id
ORDER BY COALESCE(cnt, 0) DESC");
I have tried adding a new ON statement beiside the
gf ON gf.image_id = g.id
I have also tried changing
SELECT g.*
FROM googleimage g
to
SELECT g.*
FROM googleimage WHERE user_id = 1 g
but none of them seem to work, any help will be appriciated
Try changing you query a bit like below
SELECT g.*
FROM googleimage g
LEFT JOIN (SELECT image_id, COUNT(*) AS cnt
FROM googleimagefound WHERE status = 0
GROUP BY image_id) gf ON gf.image_id = g.id
WHERE g.user_id = 1 <-- add this condition
ORDER BY COALESCE(gf.cnt, 0) DESC;
In my mysql query, I try to get all threads with their most recent row.
$query = "SELECT th.id, tm.message, tm.date_sent, tm.date_sent>tu.last_read_date AS new
FROM thread th
JOIN thread_user tu ON th.id=tu.thread_id AND tu.user_id={$user_id}
JOIN thread_message tm ON th.id=tm.thread_id
JOIN (
SELECT thread_id, MAX(date_sent) date_sent
FROM thread_message
GROUP BY thread_id
) q ON tm.thread_id = q.thread_id AND tm.date_sent = q.date_sent
ORDER BY tm.date_sent DESC";
This works, but the problem is, if there is two or more rows who's date is the most recent and they are the same date, then it will join with both of them. I need that third join statement to join with at most 1 row.
I also don't want to assume that the biggest id implies its the most recent row, because I could always change the dates manually later.
Does anyone know how to fix this?
Thanks
One way to do this is to establish a row number per group, in this case your group is thread_id and date_sent. With MySql, you need to use user-defined variables to do this:
SELECT th.id,
tm.message,
tm.date_sent,
tm.date_sent>tu.last_read_date AS new
FROM thread th
JOIN thread_user tu ON th.id=tu.thread_id AND tu.user_id={$user_id}
JOIN (
SELECT id,
thread_id,
message,
date_sent,
#rn:=IF(#prevthread_id=thread_id, #rn+1, 1) rn,
#prevthread_id:=thread_id
FROM thread_message, (SELECT #rn:=1, #prevthread_id:=0) t
ORDER BY thread_id, date_sent DESC, id
) tm ON th.id=tm.thread_id
AND tm.rn = 1
ORDER BY tm.date_sent DESC
Perhaps this is easier for you (but only because you're using mysql):
SELECT th.id,
tm.message,
tm.date_sent,
tm.date_sent>tu.last_read_date AS new
FROM thread th
JOIN thread_user tu ON th.id=tu.thread_id AND tu.user_id={$user_id}
JOIN thread_message tm ON th.id=tm.thread_id
JOIN (
SELECT thread_id,
id,
MAX(date_sent) date_sent
FROM thread_message
GROUP BY thread_id
) q ON tm.thread_id = q.thread_id
AND q.id = tm.id
AND tm.date_sent = q.date_sent
ORDER BY tm.date_sent DESC
This will return an arbitrary id to join on.
Seems to me that if the query produces what you expect, with exception of the last JOIN you can just modify the GROUP BY which will only return one row.
JOIN (
SELECT thread_id, MAX(date_sent) date_sent
FROM thread_message
GROUP BY thread_id
) q ON tm.thread_id = q.thread_id AND tm.date_sent = q.date_sent
GROUP BY tm.date_sent
ORDER BY tm.date_sent DESC";
THIS IS THE OUTPUT OF THE QUERY:
SELECT * FROM
((SELECT
privatemsgs.id,
privatemsgs.useradn,
privatemsgs.useraid,
privatemsgs.title,
privatemsgs.created,
privatemsgs.timee,
privatemsgs.isread,
u.photo AS creatorphoto,
privatemsgs.relatedto
FROM privatemsgs
LEFT JOIN
users AS u ON(privatemsgs.useraid = u.id)
WHERE userbid='$myid'
AND relatedto=0 and bdel=1)
UNION
(SELECT
privatemsgs.id,
privatemsgs.useradn,
privatemsgs.useraid,
privatemsgs.title,
privatemsgs.created,
privatemsgs.timee,
privatemsgs.isread,
u.photo AS creatorphoto,
rel.relatedto
FROM privatemsgs AS rel
JOIN privatemsgs ON(rel.relatedto = privatemsgs.id)
LEFT JOIN
users AS u ON(rel.useraid = u.id)
WHERE rel.userbid='$myid'
)) privatemsgs
GROUP BY id
ORDER BY timee DESC
I got double id "2". first 1 with "isread = 0", second with "isread = 1".
When I added "group by id", I've got (line 2)
But i need the output to show that isread = 1 (like line 3)
How do i fix it?
add MAX(isread) near the *. GROUP BY works only on Aggregate functions
I have a question.
I have here 2 tables
table 1 : products
product_id , name , images_sideview
table 2 : product_descriptions
product_id , volgnr
I want to sort them with the numbers from Table 2 and volgnr field.
Is there a way to do this with mysql ?
There are 2 ways to sort. Ascending order and Descending order. You have not mentioned the order. So I am providing you both answers with 2 variations:
ASCENDING ORDER:
SELECT DISTINCT table1.*
FROM table1
INNER JOIN table2 ON table1.product_id = table2.product_id
GROUP BY table1.product_id
ORDER BY table2.product_id ASC, table2.volgnr ASC;
DESCENDING ORDER:
SELECT DISTINCT table1.*
FROM table1
INNER JOIN table2 ON table1.product_id = table2.product_id
GROUP BY table1.product_id
ORDER BY table2.product_id DESC, table2.volgnr DESC;
If you want to tell MySQL to first sort FIRST by volgnr and then by product_id:
ASCENDING ORDER:
SELECT DISTINCT table1.*
FROM table1
INNER JOIN table2 ON table1.product_id = table2.product_id
GROUP BY table1.product_id
ORDER BY table2.volgnr ASC, table2.product_id ASC;
DESCENDING ORDER:
SELECT DISTINCT table1.*
FROM table1
INNER JOIN table2 ON table1.product_id = table2.product_id
GROUP BY table1.product_id
ORDER BY table2.volgnr DESC, table2.product_id DESC;
Hope that helps.
Edit 1:
I have now edited the query so that it does not give you duplicates in results. Try it out and let me know how that goes.
Edit 2:
Added Group By clause. Try this out.
select *
from products t1
inner join product_descriptions t2 on t1.product_id = t2.product_id
order by t2.volgnr
SELECT p.'product_id', p.'name', p.'images_sideview'
FROM products p
LEFT JOIN product_descriptions d ON p.product_id = d.product_id
ORDER BY d.volgnr;
I'm coding a listing system and I'm trying to get the posts ORDER by number of comments and votes FROM 2 tables.
Table1 : Lists => id, title, detail
Table2 : Votes => voteid, listid
Table3 : Comments => commentid, listid
WHERE MY Current query is
$q = mysql_query("SELECT * FROM zoo_leads
LEFT JOIN Votes ON Lists.id=Votes.listid
LEFT JOIN Comments ON Lists.id=Comments.listid
GROUP BY Lists.id ORDER BY Comments.listid DESC LIMIT 10
it is showing me results perfectly but ORDER BY is Lists.id Instead of number of votes and comments
Try:
SELECT *
FROM zoo_leads
LEFT JOIN votes
ON lists.id = votes.listid
LEFT JOIN comments
ON lists.id = comments.listid
GROUP BY lists.id
ORDER BY COUNT(votes.id) DESC,
COUNT(comments.id) DESC
LIMIT 10
That is because you have ORDER BY Comments.listid in your SQL statement.