MYSQL using other tables - mysql

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

Related

Order rows by amount of columns in another table

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

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.

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

MySQL query with GROUP BY and ORDER BY timestamp DESC

I am saving the history of Facebook likes for a page, identified by user_id.
Now from this table, I need to get a set representing the user_id's and their latest number of likes, based on the most recent timestamp.
I started off with this:
SELECT *
FROM facebook_log
GROUP BY user_id
ORDER BY timestamp DESC;
But that does not do what I want because it returns the first records with the lowest timestamps.
I read something online about GROUP returning the very first records from the table.
I also understood something about JOIN the table with itself, but that doesn't work either, or I did something wrong.
If you just need the user_id and the timestamp, you can just do
select f.user_id, max(f.timestamp)
from facebook_log
group by user_id;
if you need all the data from the table, you can do
select f.*
from facebook_log f
inner join (select max(timestamp) mt, user_id
from facebook_log
group by user_id) m
on m.user_id = f.user_id and m.mt = f.timestamp
You can also get the latest number of likes by using this MySQL trick:
select f.user_id, max(f.timestamp),
substring_index(group_concat(f.numlikes order by f.timestamp desc), ',', 1) as LatestLikes
from facebook_log f
group by f.user_id;

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