Order by count(*) subquery - mysql

Completely new to subqueries, I'm trying to order posts from table showcase by the number of comments they have (in descending order) and not sure how.
SELECT *
FROM showcase
ORDER BY
(select count(*)
from comments)
DESC

If you only need the ids, group by and count rows for each group
select showcase.id
from showcase left join comments on comments.item_id = showcase.id
group by showcase.id
order by count(showcase.id) desc

We need to use group by along with count:
select s.postId, count(c.commentid) as comments
from showcase s join comment c on s.postId = c.postId
group by s.postId
order by comments desc

You can try a join query which is better for query.
SELECT `showcase`.*, count(`comments`.`item_id`) as item_id FROM `showcase`
LEFT JOIN `comments`
ON `showcase`.`id`, `comments`.`item_id`
ORDER BY item_id DESC
Let me know is it work or not.

Related

How do I keep the order of my inner join in SQL?

I have the following command:
SELECT * FROM Posts P
INNER JOIN (SELECT DISTINCT ThreadId FROM Posts ORDER BY Time DESC) R
ON P.Id = R.ThreadId;
This command selects threads who contain the newest replies. Unfortunately the order of the threads seems to be random. I want the threads to be ordered by the newest replies. In other words: I want my selection to keep the order which I used inside my inner join.
How can I achieve this?
For MySql 8.0+ you can use MAX() window function in the ORDER BY clause:
SELECT *
FROM Posts
ORDER BY MAX(Time) OVER (PARTITION BY ThreadId)
For prior versions use a correlated subquery:
SELECT p1.*
FROM Posts p1
ORDER BY (SELECT MAX(p2.Time) FROM Posts p2 WHERE p2.ThreadId = p1.ThreadId)
You may also want to add as a 2nd argument in the ORDER BY clause , Time DESC.
Your join needs to group and select the last post per thread. The order needs to go on the outside query (not the subquery).
SELECT *
FROM Threads AS t
LEFT JOIN (
SELECT ThreadId, MAX(Time) AS LastPost
FROM Posts
GROUP BY ThreadId
) AS r ON r.ThreadId = t.ThreadId
ORDER BY LastPost DESC
You can use INNER JOIN instead of LEFT JOIN if you want to exclude threads that have no posts (if that is even possible).
you could change the order of your query like this
SELECT ...
FROM BrandsProducts
INNER JOIN Brands ON BrandsProducts.brandid = BrandsProducts.brandid
WHERE ...
ORDER BY ...

return all users posts ASC excepts last 7 ones left join sql

I want to return all my users posts except the last 7 ones. MySql.
The pattern would be something like this:
SELECT *
FROM posts
WHERE id_post < (SELECT * FROM posts min(id_post) WHERE id_user=4
ORDER BY id_post DESC LIMIT 7)
ORDER id_post ASC
If I Left Join with the Users table
SELECT q.*,q.id_post as id
FROM posts q
LEFT JOIN users u ON u.id_user=q.id_user
WHERE p.id_user=4
AND q.id_post < (SELECT min(rel.id_post) as min_id_post
FROM
(
SELECT p.*
FROM posts p
WHERE p.id_user=4
ORDER BY p.date DESC
LIMIT 7
) rel )
I retrieve the results by this last query, but it has so many subqueries...
Is it a subquery needed to achive what I want? Is there a shorter version?
You don't need an Outer Join (in fact the WHERE p.id_user=4 turns it into an Inner Join anyway).
You should be able to use a LIMIT to skip the first 7 rows:
SELECT q.*,q.id_post as id
FROM
( SELECT
FROM posts AS p
WHERE p.id_user=4
ORDER BY p.date DESC
LIMIT 8, 999999999
) q
JOIN users u ON u.id_user=q.id_user
WHERE u.id_user=4
ORDER id_post ASC
And your current query doesn't need to join to users, you don't access any column from that table (but this was probably a stripped down version)

Using UNION, JOIN and ORDER by to Merge 2 identical tables

I need to join 2 identical tables to display the same list sorted by id. (posts and posts2)
It happens that before only worked with 1 table, but we've been using a second table (posts2) to store the new data from a certain id.
This is the query I used when I worked with 1 table(posts) and works fine.
select posts.id_usu,posts.id_cat,posts.titulo,posts.html,posts.slug,posts.fecha,hits.id,hits.hits,usuarios.id,usuarios.usuario,posts.id
From posts
Join hits On posts.id = hits.id
Join usuarios On posts.id_usu = usuarios.id
where posts.id_cat='".$catid."' order by posts.id desc
Now I tried to apply this query to Union 2 tables, but I don't know at what point instantiate the JOINS. I tried several ways but sends MYSQL Error. The following query merge the 2 tables and order by id, but need to add the JOIN.
select * from (
SELECT posts.id,posts.id_usu,posts.id_cat,posts.titulo,posts.html,posts.slug,posts.fecha
FROM posts where id_cat='6' ORDER BY id
)X
UNION ALL
SELECT posts2.id,posts2.id_usu,posts2.id_cat,posts2.titulo,posts2.html,posts2.slug,posts2.fecha FROM posts2 where id_cat='4' ORDER BY id DESC limit 20
I need to add this at the above query
Join hits On posts.id = hits.id
Join usuarios On posts.id_usu = usuarios.id
Thanks in advance guys.
If you want the same query as your first query but this time with union of your identical table i.e post2 then you can do so
select
p.id_usu,p.id_cat,p.titulo,p.html,p.slug,p.fecha
,hits.id,hits.hits,usuarios.id,usuarios.usuario
from (
(select
id_usu,id_cat,titulo,html,slug,fecha ,id
From posts
where id_cat='".$catid."' order by id desc limit 20)
UNION ALL
(select
id_usu,id_cat,titulo,html,slug,fecha ,id
From posts2
where id_cat='".$catid."' order by id desc limit 20)
) p
Join hits On p.id = hits.id
Join usuarios On p.id_usu = usuarios.id
order by p.id desc limit 20

Attempting to write a COUNT(*) Query

Write a query that returns the names of the top five customers who have purchased the most songs from ATunes, ordered by the number of purchases (descending). I must also limit the results to the top 5 as stated.
SELECT P.CustomerID, A.FirstName, A.LastName, P.DateOfPurchase, COUNT(DateOfPurchase) as NumberOfPurchases
ORDER BY NumberOfPurchases DESC, LIMIT 0,5
FROM Purchases as P
JOIN ATunesCostumers as A on (A.CustomerID = P.CustomerID)
GROUP BY CustomerID;
this is what I am trying, and I am getting a syntax error.
When I get rid of the ORDER BY and LIMIT statements I get everything I need for this, other than the limitation and correct ordering. I'm at a loss, does anyone know what I am doing wrong?
Try this:
SELECT P.CustomerID, A.FirstName, A.LastName, P.DateOfPurchase, COUNT(DateOfPurchase) as NumberOfPurchases
FROM Purchases as P
JOIN ATunesCostumers as A on P.CustomerID = A.CustomerID
GROUP BY CustomerID
ORDER BY NumberOfPurchases DESC LIMIT 0,5;

MySQL query already GROUPed and ORDERed : how to ORDER inside the GROUPs?

I have this query:
SELECT id_user, COUNT(*) as count
FROM posts
GROUP BY id_user
ORDER BY COUNT(*) DESC
which gives me the id_user ordered by occurrences, and the number of each occurrence.
Can I get, in the same request, the LAST post from each 'id_user'? i.e. I want to select the last 'post' too, but when I do
SELECT id_user, post, COUNT(*) as count
Tthe value in 'post' isn't the last one (nor the first one; actually I don't know how groups are ordered). Should I run another query?
I believe u can accomplish this by adding max(post_id) last_post to your select.
This ought to do it in one query:
SELECT
p.id_user,
ap.post AS last_post,
COUNT(*) as count
FROM
posts p
JOIN posts ap on (
p.id_user = ap.id_user
AND ap.post_id = (
SELECT MAX(post_id) FROM posts ip WHERE p.id_user = ip.id_user
)
GROUP BY
p.id_user,
ap.post
ORDER BY
COUNT(*) DESC