Order rows by amount of columns in another table - mysql

I'm currently outputting all of my members by adding the MySQL clause ORDER BY id DESC, but I feel that doesn't reward people that are active on my service.
I thought about judging the order by the amount of entries in another table they have under their ID.
Essentially, I'm asking if it's possible to order columns in a MAIN table counting the amount of rows where the users ID is in the column of the row.
Something pseudo to this
SELECT user_id,name,etc FROM users ORDER BY (
COUNT(SELECT FROM users_interactions WHERE user_id = user_id) *******
) ASC
In the end of the COUNT statement, the user_id = user_id was just a guess.

You are almost there - what you need to do is to put COUNT inside SELECT:
SELECT user_id,name,etc FROM users u ORDER BY (
SELECT COUNT(*)
FROM users_interactions i
WHERE i.user_id = u.user_id
) ASC
You could also do it using a JOIN, like this:
SELECT u.user_id, u.name, u.etc
FROM users u
LEFT OUTER JOIN users_interactions i ON i.user_id = u.user_id
GROUP BY u.user_id, u.name, u.etc
ORDER BY COUNT(*) ASC

Related

Find rank with query in MySql

I know that this question is asked also before but i tried all of them but no one works for me because my query is a little bit different because it has sum function in query that needs to get sum and in base of sum to get the rank of the user.
So my question is how to find the rank for single user my table is this:
currently i am trying with this query but this gives me all users.
SELECT u.user_name as userName
, sum(taken_quiz_points) as totalPoints
FROM taken_quiz as q
, users_app as u
WHERE q.taken_quiz_user_id = u.user_id
GROUP
BY taken_quiz_user_id
ORDER
BY totalPoints DESC
First of all, you should use INNER JOIN when you query data from multiple tables.
Also, I don't think it's possible to ORDER BY an alias, you have to repeat the operation of the alias.
If you want to have the rank of a single user you have to add a WHERE condition, like WHERE u.name = "toto" or something.
You should end up with this :
SELECT
u.user_name as userName ,
sum(q.taken_quiz_points) as totalPoints
FROM taken_quiz q
INNER JOIN users_app u ON q.taken_quiz_user_id = u.user_id
WHERE u.name = "toto"
GROUP BY q.taken_quiz_user_id
ORDER BY sum(q.taken_quiz_points) DESC
So you need the whole dataset in order to know the ranking of the person. It's a bit ugly, but you can nest to get the ranking, and then select from the ranked dataset the person you are interested in:-
Select userName, user_rank from
(Select userName,totalpoints ,dense_rank() OVER (Order by totalpoints desc) as user_rank
from (
SELECT u.user_name as userName ,sum(taken_quiz_points) as totalPoints
FROM taken_quiz as q, users_app as u
WHERE q.taken_quiz_user_id=u.user_id GROUP BY user_name,
taken_quiz_user_id) aa
) bb
where userName ='bob'

SQL intermediate table having column = max(column)

I have 2 tables: user and review, a one-to-many relationship.
When I execute the following query:
SELECT
user_id,
count(*) totalReviews,
USER . NAME
FROM
review,
USER
WHERE
USER .id = review.user_id
GROUP BY
user_id
I get:
1 2 marius
2 2 daniela
3 1 alin
What I want to do now is to display first 2 users because they have given the most reviews(2).
I tried adding having, if I hardcode having totalReviews=2 it works, but if I write having total = max(total) I get 0 results, while if I'm trying with,
SELECT
*
FROM
(
SELECT
user_id,
count(*) total,
USER . NAME
FROM
review,
USER
WHERE
USER .id = review.user_id
GROUP BY
user_id
) A
WHERE
total = (SELECT max(total) FROM A) `
I get an error (table A doesn't exist)
You would do this with ORDER BY and LIMIT:
SELECT u.id, count(*) as totalReviews, u.name
FROM review r JOIN
user u
ON u.id = r.user_id
GROUP BY u.id, u.name
ORDER BY totalReviews DESC
LIMIT 2;
Notes:
Never use commas in the FROM clause. Always use proper, explicit JOIN syntax.
Table aliases make the query easier to write and read.
EDIT:
If occurs to me that you want all users with the maximum number of reviews, not exactly 2. Here is one method:
SELECT u.id, COUNT(*) as totalReviews, u.name
FROM review r JOIN
user u
ON u.id = r.user_id
GROUP BY u.id, u.name
HAVING totalReviews = (SELECT COUNT(*)
FROM review r2
GROUP BY r2.user_id
ORDER BY COUNT(*) DESC
LIMIT 1
);
Note that the subquery in the HAVING clause is simpler than the outer query. There is no need to bring in the user name.

SQL query to fetch the last users who created content orderd by date

I have a oneToMany relationship between User entity and Post entity. Each user can create as muck posts as he want. Tables look like:
User(id, name)
Post(id, post_owner_id, content, date) // post_owner_id is the foreign key
My goal is to fetch the last users who created posts. I started by:
SELECT *
FROM `post`
ORDER BY post_date DESC
LIMIT 0 , 30
and it is giving me correct result. But when I add GROUP BY post_user_id, it shrinks the result to only one row per user but with unordered date. What am I missing?
I believe that I need a JOIN to get the final goal but I need first to find a solution for this first part. Your help is much appreciated.
I need a table of users with the date of their last post.
SELECT post_owner_id, max(date) as maxdt
FROM `post`
group by post_owner_id
order by maxdt desc
limit 0,30
select id, maxdt, name
from (
SELECT post_owner_id, max(date) as maxdt
FROM `post`
group by post_owner_id) t join `User` u on u.id = t.post_owner_id
You don't even need a sub query.
SELECT u.id, u.name, max(p.`date`) as maxdt
FROM `post` p
JOIN `User` u on u on u.id = p.post_owner_id
group by u.id, u.name

MYSQL using other tables

This query:
SELECT
user_id,
count(base_item)
FROM items
WHERE base_item = '202'
group by user_id order by count(base_item)
Gives me this result:
which I want.
However, I also want it to exclude all user ids in the users table with a rank of 5 or greater. as shown here
Modify your where clause this way:
WHERE base_item = '202' AND user_id NOT IN (SELECT id FROM users WHERE rank > 5)
The portion in parentheses is called a subquery. The result set of the subquery contains the id of all users with a rank greater than 5. The addition to the where clause excludes all users in that result set.
Join with the users table and filter out rows with high rank
SELECT user_id, count(*) AS count
FROM items AS i
JOIN users AS u ON i.user_id = u.id
WHERE i.base_item = '202'
AND u.rank <= 5
group by user_id
order by count

MYSQL Query of four tables

I'm stuck doing a query. I'd like to extract the 10 first records of one table considering the values of the other three tables. I'll try to explain what I want with an example:
TABLES
USERS: username and date
POINTS: id_user, points
COMMENTS: id_user
WON: id_user
THE CRITERIA MUST BE: The 10 users who have more points and, in case of equal values, with more comments published, less recent date date and didn't won. In that order.
SELECT id, username, date FROM users as us LIMIT 10 ORDER BY date DESC JOIN id_user, points FROM points as po WHERE us.id = po.id_user ORDER BY po.points DESC JOIN COUNT (id_user) FROM comments JOIN COUNT (id_user) FROM won;
I know that's wrong... :(
Assuming Users has an id field and a created datetime field, I think you're looking for something like this
SELECT *
FROM Users
LEFT JOIN Points ON Points.id_user = Users.id
LEFT JOIN Comments ON Comments.id_user = Users.id
LEFT JOIN Won ON Won.id_user = Users.id
GROUP BY Users.id
ORDER BY SUM(Points.points) DESC, COUNT(Comments.id) DESC, MAX(Users.created) DESC, COUNT(Won.id) DESC