i have this
SELECT COUNT(1) cnt, a.auther_id
FROM `posts` a
LEFT JOIN users u ON a.auther_id = u.id
GROUP BY a.auther_id
ORDER BY cnt DESC
LIMIT 20
its work fine
bu now i want select from posts which added from 1 day tried to use
WHERE from_unixtime(post_time) >= SUBDATE(NOW(),1)
but its didnot worked
any one have idea
My guess is that you added the WHERE clause in the wrong place. It should come after the JOIN but before the GROUP BY, like this:
SELECT COUNT(1) cnt, a.auther_id
FROM `posts` a
LEFT JOIN users u ON a.auther_id = u.id
WHERE from_unixtime(post_time) >= SUBDATE(NOW(),1)
GROUP BY a.auther_id
ORDER BY cnt DESC
LIMIT 20
Related
I'm trying to retrieve the last 10 posts from a posts table ordered ASC, but the last left joined query doesn't retrieve anything.
Basic: it retrieves results ordered DESC
SELECT
p.post, p.id_post, u.name
FROM
posts p
LEFT JOIN
users u ON u.id_user = p.id_user
WHERE
p.id_user = 4
ORDER BY
p.date DESC
LIMIT 10
Ordered ASC: it doesn't work at all:
SELECT
num.*
FROM
(SELECT
p.post, p.id_post, u.name
FROM
posts p
LEFT JOIN
users u ON u.id_user = p.id_user
WHERE
p.id_user = 4
ORDER BY
p.date DESC
LIMIT 10) num
ORDER BY
p.date ASC
What am I doing wrong?
In my php variables I use $row['id_post'] $row['post'] $row['name']. I don't want to use array_reverse() just plain sql
You need to return the date in the subquery:
SELECT pu.post, pu.id_post, pu.name
FROM (SELECT p.*, u.name
FROM posts p LEFT JOIN
users u
ON u.id_user = p.id_user
WHERE p.id_user = 4
ORDER BY p.date DESC
LIMIT 10
) pu
ORDER BY pu.date ASC;
Your second query should have returned an error message to the effect that date is not recognized as a column. You should be capturing and reading error messages, if you want to write an effective application.
What I want:
SELECT u.username, u.last_activity
FROM users_userprofile
WHERE u.id IN (
SELECT DISTINCT(p.user_id) FROM forums_post p
WHERE p.thread_id = 423993
ORDER BY p.created_at DESC
LIMIT 4
);
This doesn't work because of LIMIT in subquery. I want to keep order of subquery but I want to get username and last_activity instead of user_id.
Any suggestion how I could achieve this?
Replace the subquery with a view:
CREATE VIEW subv AS SELECT p.user_id FROM forums_post p
WHERE p.thread_id = 423993
ORDER BY p.created_at DESC
LIMIT 4;
SELECT u.username, u.last_activity
FROM users_userprofile
WHERE u.id IN (SELECT * FROM subv);
you could use join for the table and the subquery instead of using where in:
SELECT u.username, u.last_activity
FROM users_userprofile u
JOIN (
SELECT p.user_id FROM forums_post p
WHERE p.thread_id = 423993
ORDER BY p.created_at DESC
LIMIT 4
) q
on u.user_id=q.user_id
Why woldn't you do it with a JOIN? There seems to be no performance impact because WHERE and LIMIT clauses are the same. It won't JOIN the whole tables:
SELECT p.user_id, u.username, u.last_activity
FROM users_userprofile u
JOIN forums_post p ON p.user_id = u.id
WHERE p.thread_id = 423993
GROUP BY p.user_id ORDER BY MAX(p.created_at) DESC
LIMIT 4
I'm trying to fetch 100 posts and order them by the number of times they've been "remixed" in the last week. Here is my query thus far:
SELECT COUNT(remixes.post_id) AS count, posts.title
FROM posts
LEFT JOIN (
SELECT * FROM remixes WHERE created_at >= 1343053513
) AS remixes ON posts.id = remixes.post_id
GROUP BY posts.id
ORDER BY count DESC, posts.created_at DESC
LIMIT 100
This produces the correct result; however, after running DESCRIBE I get this:
And here are my indexes on posts:
And my indexes on remixes:
And here are my questions:
Can you explain what the terms used in the extra column are really trying to tell me?
Could you provide tips on how I can optimize this query so that it'll scale better.
Thanks in advance!
Update
Per Zane's solution, I've updated my query to:
SELECT COUNT(remixes.post_id) AS count, posts.title
FROM posts
LEFT JOIN remixes ON posts.id = remixes.post_id AND remixes.created_at >= 1343053513
GROUP BY posts.id
ORDER BY count DESC, posts.created_at DESC
LIMIT 100
And here's the latest DESCRIBE
I'm still worried about the filesort part. Any ideas?
Try not to wrap your JOIN in a sub-select as this will create an unindexed temporary table to store the result of the subselect in, where it then joins on that unindexed table.
Instead, put created_at as an additional join condition when joining the remixes table:
SELECT
a.title, COUNT(b.post_id) AS remixcnt
FROM
posts a
LEFT JOIN
remixes b ON a.id = b.post_id AND b.created_at >= 1343053513
GROUP BY
a.id, a.title
ORDER BY
remixcnt DESC, a.created_at DESC
LIMIT 100
It seems to me that
SELECT COUNT(remixes.post_id) AS count, posts.title
FROM posts
LEFT JOIN (
SELECT * FROM remixes WHERE created_at >= 1343053513
) AS remixes ON posts.id = remixes.post_id
GROUP BY posts.id
ORDER BY count DESC, posts.created_at DESC
LIMIT 100
could be rewritten as
SELECT COUNT(r.post_id) AS count, posts.title
FROM posts
LEFT JOIN remixes r ON posts.id = r.post_id
WHERE r.created_at >= 1343053513
GROUP BY posts.id
ORDER BY count DESC, posts.created_at DESC
LIMIT 100
which should give you a better EXPLAIN plan and run faster.
I have this
SELECT COUNT(1) cnt, a.auther_id
FROM `posts` a
LEFT JOIN users u ON a.auther_id = u.id
GROUP BY a.auther_id
ORDER BY cnt DESC
LIMIT 20
It works fine, but now I want select posts from within the last day. I tried to use
WHERE from_unixtime(post_time) >= SUBDATE(NOW(),1)
but it didn't work. Any one have idea why?
This may work:
WHERE FROM_UNIXTIME(post_time) >= SUBDATE(NOW(), INTERVAL 1 DAY)
i have users table and i have posts table i want select from users the top users that have the big amount of posts from posts table and order them by numbers of posts
i can make it by array_count_values() by i cant order it
now i think if i make it by one mysql query by left and join will be more better
table structure
posts
id | auther_id
i tried this
SELECT COUNT(1) cnt, u.user_id
FROM users u
LEFT JOIN posts p
ON p.author_id=u.user_id
GROUP BY u.user_id
ORDER BY cnt DESC
LIMIT 20
it gave me this
alt text http://img511.imageshack.us/img511/6707/31154352.gif
see the arrow
what is this
i just have 2 posts under user_id 5
what is this first row
You need to aggregate the posts by user using GROUP BY u.user_id, get a COUNT value for the number of posts and ORDER BY that number, in descending order:
SELECT COUNT(1) cnt, u.user_id
FROM users u
LEFT JOIN posts p
ON p.author_id=u.user_id
GROUP BY u.user_id
ORDER BY cnt DESC
LIMIT 20
SELECT u.user_id, COUNT(*) as post_count
FROM users u
INNER JOIN posts p
USING (user_id)
GROUP BY u.user_id
ORDER BY post_count
i used this and its worked
is it true
SELECT COUNT( 1 ) cnt, a.auther_id
FROM `posts` a
LEFT JOIN users u ON a.auther_id = u.id
GROUP BY a.auther_id
ORDER BY cnt DESC
LIMIT 20