1

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.

2
  • from which table does visibility belongs to? Commented May 7, 2010 at 13:04
  • i have answered in post a minute ago Commented May 7, 2010 at 13:30

3 Answers 3

2

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
Sign up to request clarification or add additional context in comments.

6 Comments

it not looks like it has subqueries but it has. see dev.mysql.com/doc/refman/5.0/en/explain.html
it's not subquery(where the query pingpong back and forth on 3 tables). it's called table deriving, table deriving is more efficient. but table deriving is more elegant if MySQL already has CTE
@Maksim: try to discern the difference between table deriving(efficient) and subquery(inefficient)
try to have a feel of first class table deriving, download MSSQL or Postgresql and google CTE(common table expression). sadly, MySQL doesn't have CTE yet, so you have to extract intermediate result from other query by enclosing it in parenthesis, this is called table deriving, not subquery
ohohoh, its doesnt work, errors. and is it really will be more faster? thx for help
|
0

you can store vote sum and post count in a 'users' table and update them via trigger or 'update' query.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.