0
SELECT 
links.id, 
links.url, 
links.user_id, 
links.title, 
links.description, 
links.nsfw, 
links.posted, 
links.category_id,

votes.vote
votes.vote_date

FROM links 

INNER JOIN votes
ON votes.link_id = links.id

ORDER BY (I want to sort by the count of votes on the links) DESC

If I want to sort my links/posts by votes, how can I then do it with this SQL? The link with the highest vote count shows first.

  • The thing is unclear. You want a list of links sorted by *average* vote? By most voted? By highest-given-vote? ..? – redShadow Dec 18 '11 at 17:59

4 Answers4

1

You want grouping. Try this:

SELECT 
  links.id, 
  links.url, 
  links.user_id, 
  links.title, 
  links.description, 
  links.nsfw, 
  links.posted, 
  links.category_id
FROM 
  links 
  INNER JOIN votes ON votes.link_id = links.id
GROUP BY links.id
ORDER BY COUNT(votes.id) DESC

I didn't test it (because I don't have your dataset), but it should be more or less correct.

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
0
  1. Group by link id and select thee vot count

    SELECT
        count(*) as votecount,
        links.id, 
        links.url, 
        links.user_id, 
        links.title, 
        links.description, 
        links.nsfw, 
        links.posted, 
        links.category_id,
        votes.vote
        votes.vote_date
    FROM links 
    INNER JOIN votes
        ON votes.link_id = links.id
    GROUP BY links.id
    

2.) Wrap this in a superquery for sorting

SELECT * FROM (
    <as above>
) AS baseview
ORDER BY votecount DESC
Eugen Rieck
  • 64,175
  • 10
  • 70
  • 92
  • The difference between this solution and the one by @SergeiTulentsev is, that the inner query will go to the query cache. Assuming you might need it for display later on, this is a good thing. – Eugen Rieck Dec 18 '11 at 17:56
  • query cache gets invalidated on every table mutation. So I never rely on this :-) – Sergio Tulentsev Dec 18 '11 at 17:57
0

You can use a subquery:

SELECT links.id, links.url, votes.vote, votes.vote_date
FROM links
INNER JOIN votes ON votes.link_id = links.id
INNER JOIN (
    SELECT links.id AS link_id, COUNT(votes.id) AS num_votes
    FROM links
    INNER JOIN votes ON votes.link_id = links.id
    GROUP BY links.id
) AS votes_per_link ON links.id=votes_per_link.link_id
ORDER BY votes_per_link.num_votes DESC
Álvaro González
  • 142,137
  • 41
  • 261
  • 360
0

Since I didn't understand which of these behaviors you are asking for, I post solutions to different cases here:

Get links, order by highest vote:

SELECT votes.link_id, links.url, MAX(votes.vote) AS maxvote
FROM votes INNER JOIN links ON links.id = votes.link_id
GROUP BY votes.link_id ORDER BY `maxvote` DESC;

Get links, order by average vote:

SELECT votes.link_id, links.url, AVG(votes.vote) AS avgvote
FROM votes INNER JOIN links ON links.id = votes.link_id
GROUP BY votes.link_id ORDER BY `avgvote` DESC;

Get links, order by votes count:

SELECT votes.link_id, links.url, COUNT(votes.vote) AS cntvotes
FROM votes INNER JOIN links ON links.id = votes.link_id
GROUP BY votes.link_id ORDER BY `cntvotes` DESC;

Get votes, by highest vote:

SELECT links.id, links.url, votes.vote
FROM links INNER JOIN votes ON links.id = votes.link_id
ORDER BY votes.vote DESC;

(I omitted some fields to shorten queries, of course feel free to add them back again).

redShadow
  • 6,687
  • 2
  • 31
  • 34