I've setup a contest where video submissions are sent in and then people vote on them. Submissions are sent into a table submissions with this structure:
submission_id, title, videoname
The voting table votes structure is:
video_id, voter_id
The video_id correlates to the submission_id in the submissions table.
I want to get the number of votes for each video like so:
select video_id, count(1) from votes group by submission_id
But I also want to display the title for each video so the result would be:
video_id, count, title
I am a sql noob so please forgive me if this is a simple statement. I have done some research and was not able to come up with something on my own and would appreciate any help.
I would recommend doing a LEFT JOIN instead of an INNER JOIN... and COUNT(v.video_id) instead of COUNT(*). This way you will still return submissions that currently have 0 votes:
select
s.submission_id as video_id,
count(v.video_id) as vote_count,
s.title
from
submissions s
left join votes v on v.video_id = s.submission_id
group by
s.submission_id,
s.title
select s.submission_id, s.title, s.videoname, c.cnt
from
submissions s,
(select video_id, count(1) as cnt from votes group by video_id) c
where
s.submission_id = c.video_id
This will return every video from you submissions table and show the number of votes in the votes table. If there have not been any votes it will show up in the results with a NULL as the Votes column
SELECT video_id, title, COUNT(voter_id) Votes
FROM submissions s
LEFT OUTER JOIN votes v ON s.submission_id = v.video_id
GROUP BY video_id, title,
You have to make a join for retrieve the votes and the video title, between the two tables like this :
SELECT submissions.submission_id
, COUNT(1)
, submissions.videoname
FROM submissions LEFT OUTER JOIN votes
ON votes.video_id = submissions.submission_id
GROUP BY submissions.submission_id, submissions.videoname
Related
This my query:
Select articles.id,articles.userid,articles.article,count(articles_likes.id), count(article_dislikes.id)
from articles
Left join article_likes
on article_likes.id=articles.id
Left join article_dislikes
on article_dislikes.id=articles.id
group by articles.id ;
I want to count the number of rows in article_likes table and article_dislikes table im getting the value correct upto 2 rows..when there is a third and so on entries..I'm getting wrong counting of rows...
I don't know where the problem is ..I think I may be getting wrong values because I'm using the same table for two times...please help me
I have three tables
1)articles contains id,userid and article
2)Articles_likes table contains-like_id ,user_id and article_id
3)Articles_dislikes table contains dislike_id ,user_id and article_id
Aggregate separately in each of the tables articles_likes and articles_dislikes and then join articles to the results:
select a.id, a.userid, a.article,
coalesce(l.likes, 0) likes,
coalesce(d.dislikes, 0) dislikes
from articles a
left join (
select article_id, count(*) likes,
from articles_likes
group by article_id
) l on l.article_id = a.id
left join (
select article_id, count(*) dislikes,
from articles_dislikes
group by article_id
) d on d.article_id = a.id
Also the correct join of articles_likes and articles_dislikes to articles is by the column article_id to the id of articles.
I'm generating a query where I'm getting list of userid's seprated by comma using GROUP_CONCAT. I want to count these IDs in the same query. Can I do so?
$query="SELECT id,
longitude,
latitude,
game_date,
min_player,
game_description,
is_public,
is_user_coming,
allow_player_invite,
location,
game_type,
game_status,
cdate,
ownerid,
COUNT(j.users) as joinees,
users.username
FROM games
left join
(SELECT gameid, GROUP_CONCAT(userid, ',') as users
from user_game_join where games.id=user_game_join.gameid) j on j.gameid=id
join (select id as uid,name as username from users) users on users.uid=ownerid
AND (`location` LIKE '$location%' or `location` LIKE '".ucfirst($location)."%')";
This is my query and I need to get the number of joineers. Attached herewith is the snapshot of my tables:
SELECT gameid,
GROUP_CONCAT(userid, ',') as users,
count(userid) as user_count
from user_game_join
where games.id = user_game_join.gameid
A friend of mine helped me with that. Surprisingly, I was using join in wrong place. Sharing the query just in case someone might find it helpful:
SELECT games.*,ugj.joinees,u.username FROM games JOIN
(select id as uid, name as username from users) users on users.uid = games.ownerid
AND games.id='$gid' left join
(select count(userid) as joinees,gameid as gid from user_game_join group by gameid ) ugj on games.id=ugj.gid LEFT JOIN
(select id,name as username from users) u on u.id=games.ownerid
I haven't used pure mySQL for a while now and looks like I forgot it. Sad story.
Now I have 2 tables - images and votes. Images have a unique id, among others. The votes table only has 2 fields - image id and user id.
I'm trying to get the list of images ordered by number of votes and I'm kinda stuck here. The closest I got is this:
SELECT i.uname AS author, i.title, i.time, i.description, i.id, i.extension, v.uid
FROM images as i
LEFT JOIN
votes as v ON i.id = v.iid
Which returns all images with the voter ID. If an image has multiple votes, than it's returned more than once.
Can someone please help me with this query ?
You need to use COUNT and GROUP BY:
SELECT i.uname AS author, i.title, i.time, i.description, i.id, i.extension, COUNT(v.uid)
FROM images as i
LEFT JOIN votes as v ON i.id = v.iid
GROUP BY i.uname, i.title, i.time, i.description, i.id, i.extension
ORDER BY Count(v.uid) DESC
As suggested, you don't have to GROUP BY all your output fields in MySQL -- just use your unique identifier, in this case, i.id.
Try:
SELECT i.uname AS author, i.title, i.time, i.description, i.id, i.extension, count(*) votes
FROM images as i
LEFT JOIN votes as v ON i.id = v.iid
group by i.id
order by 7
(from lowest to highest - add desc after order by 7 to change the sort order to be from highest to lowest.)
I'm working on a site with images and tags on the images (à la Facebook). Images are in albums.
The important bits of the DB structure are as follows
user: id INT
album: id INT, user_id INT
photo: id INT, album_id INT
tag: id INT, photo_id
I'm trying to get a call working that'll return, given a user_id, the album id, the total number of photos in that album, and the total tags in that album.
It's working fine to get either the total photos or the total tags, but not both. In that case, it returns the total number of tags twice.
The following is my SQL call:
SELECT album.id, COUNT(photo.id), COUNT(tag.id)
FROM album
LEFT OUTER JOIN photo ON (album.id = photo.album_id)
LEFT OUTER JOIN tag ON (photo.id = tag.photo_id)
WHERE album.user_id = 123 GROUP BY album.id
ORDER BY album.id DESC LIMIT 0,25
Any ideas how I could do this better?
You could add a DISTINCT to the count
ie:
COUNT(DISTINCT photo.id),
COUNT(DISTINCT tag.id)
SELECT
album.id AS album_id,
COUNT(DISTINCT photo.id) AS count_photos,
COUNT(DISTINCT tag,id) AS count_tags
FROM album
LEFT JOIN photo ON album.id=photo.album_id
LEFT JOIN photo ON photo.id=tag.photo_id
WHERE album.user_id = 123
GROUP BY album.id
The problem that you have is because you are joining along two different dimensions, photos and tags. Although COUNT(DISTINCT) works for counts, you might want to aggregate other information as well.
The more general approach is to separate the results into subqueries:
SELECT a.id, NumPhotos, NumTags
FROM (select album.id, count(*) as NumPhotos
from album LEFT OUTER JOIN
photo
ON (album.id = photo.album_id)
) a LEFT OUTER JOIN
(select album.id, count(*) as NumTags
from album LEFT OUTER JOIN
photo
ON (album.id = photo.album_id) LEFT OUTER JOIN
tag
ON (photo.id = tag.photo_id)
) b
on a.id = b.id
WHERE a.user_id = 123
ORDER BY a.id DESC
LIMIT 0,25
Can we do this query without subqueries?
SELECT login, post_n,
(SELECT SUM(vote) FROM votes WHERE votes.post_n=posts.post_n)AS votes,
(SELECT COUNT(comments.post_n) FROM comments WHERE comments.post_n=posts.post_n)AS comments_count
FROM users, posts
WHERE posts.id=users.id AND (visibility=2 OR visibility=3)
ORDER BY date DESC LIMIT 0, 15
tables:
Users: id, login
Posts: post_n, id, visibility
Votes: post_n, vote
id — it`s user id, Users the main table.
Yeah, it's possible:
SELECT login, post_n,
SUM(vote) as votes,
FROM users
JOIN posts using(id)
LEFT JOIN votes using(post_n)
WHERE visibility=2 OR visibility=3
GROUP BY login, post_n
Then flatten the result:
select * from
(
SELECT login, post_n,
SUM(vote) as votes,
FROM users
LEFT JOIN posts using(id)
LEFT JOIN votes using(post_n)
WHERE visibility=2 OR visibility=3
GROUP BY login, post_n
) as votes_count
Then join the comments:
select votes_count.login, votes_count.post_n, votes_count.votes,
COUNT(comments.post_n) as comments_count
from
(
SELECT login, post_n,
SUM(vote) as votes,
FROM users
LEFT JOIN posts using(id)
LEFT JOIN votes using(post_n)
WHERE visibility=2 OR visibility=3
GROUP BY login, post_n
) as votes_count
LEFT JOIN comments using(post_n)
GROUP BY votes_count.login, votes_count.post_n
ORDER BY date DESC LIMIT 0, 15
you can store vote sum and post count in a 'users' table and update them via trigger or 'update' query.
i have test both variants and test variant when we using join or where to merge our tables.
No subqueries variant more slow, 0.0208 sec, and mysql use only 271 rows in votes table, but when i have use joins it use whole rows. Here no subqueries variant:
SELECT res.*, COUNT(*) FROM
(
SELECT login, posts.post_n, SUM(vote)AS votes
FROM users, posts, votes
WHERE users.id=posts.id AND posts.post_n=votes.post_n AND visibility=3
GROUP BY posts.post_n
)AS res, comments
WHERE comments.post_n=res.post_n
GROUP BY res.post_n
ORDER BY date DESC
LIMIT 0, 15
And subqueries varian performed only 0.0027 sec, it`s no cache but using indexes in all tests.
p.s. sorry for my english