I need to select the users who have won at least 1 round in all of the different competitions.
I have the following table sctructure:
results
id
round_id
user_id
result
1
1
2
1
2
1
1
2
rounds
id
category_id
1
1
2
1
3
2
4
2
categories championship
id
competition_id
1
1
2
2
competitions team
id
competition_name
1
Competition A
2
Competition B
Now let's say Bob has won at least 1 round in both Competition A and B each, he needs to show up in the list. But Joe, who's won 1 round in Competition A but nothing in Competition B, must not show up.
I tried writing a script like this, but I can see the flaw in my logic. It's looking for a row where the round_id is both 1 and 2 is impossible.
SELECT user_id FROM results WHERE
(result = 1 AND round_id IN
(SELECT id FROM rounds WHERE category_id IN
(SELECT id FROM categories WHERE competition_id = 7)
)
) AND
(result = 1 AND round_id IN
(SELECT id FROM rounds WHERE category_id IN
(SELECT id FROM categories WHERE competition_id = 8)
)
) AND
(result = 1 AND round_id IN
(SELECT id FROM rounds WHERE category_id IN
(SELECT id FROM categories WHERE competition_id = 9)
)
)
GROUP BY driver_id
How can I achieve this?
Join results to rounds and categories (competitions is not needed because competition_id exists in categories).
Then filter the rows for only the users who won at least one round and aggregate by user with the condition in the HAVING clause for the user that all 3 competition_ids are returned:
SELECT rs.user_id
FROM results rs
INNER JOIN rounds rd ON rd.id = rs.round_id
INNER JOIN categories cg ON cg.id = rd.category_id
WHERE rs.result = 1 AND cg.competition_id IN (7, 8, 9)
GROUP BY rs.user_id
HAVING COUNT(DISTINCT cg.competition_id) = 3;
Related
I have two mysql transactional tables and and two lookup tables. I want to select max(id) from each of the transactional tables, combine the results with lookup tables and combine into one row. I seem unable to find solutions so far. Here is my tables. Stocks and Prices are transactional while Vehicle and Models are lookup tables.
Vehicles table
id name
1 Toyota
2 Suzuki
Models table
id vehicle_id name
1 1 Corolla
2 2 Swift
3 1 Prado
4 2 Vitara
Stocks table
id vehicle_id model_id qty
1 1 1 50
2 2 2 77
3 1 1 40
4 2 2 30
Prices table
id vehicle_id model_id price
1 1 1 500
2 2 2 777
3 1 1 600
4 2 2 1000
Expected results
id vehicle_id model_id qty price vname mname
1 1 1 40 600 Toyota Corolla
2 2 2 30 1000 Suzuki Swift
Here is what I've tried among countless trials
select s.*, b.name vehicle, m.name model, p.price
from stocks s, vehicles b, models m, prices p
where s.id in (select max(id) id from stocks
where s.vehicle_id = b.id and s.model_id = m.id and s.vehicle_id = p.vehicle_id and s.model_id = p.model_id
group by vehicle_id, model_id)
order by id;
Running the above query doesn't give me what I want and it crushes the PC. I have to restart. How can I achieve the expected outcome?
If you are using MySQL 8 you can use window functions and common table expressions for latest(based on maximum id per vehicle and model group) prices and qty for vehicle and models
with pricescte as (select *,
rank() over (partition by vehicle_id,model_id order by id desc) AS price_rank
from prices),
stockcte as (select *,
rank() over (partition by vehicle_id,model_id order by id desc) AS stock_rank
from stocks)
select v.id,
v.name,
m.id as model_id,
m.name,
s.qty,
p.price
from vehicles v
join models m on v.id = m.vehicle_id
join stockcte s on v.id = s.vehicle_id
and m.id = s.model_id
join pricescte p on v.id = p.vehicle_id
and m.id = p.model_id
where s.stock_rank = 1
and p.price_rank = 1
DEMO
If you are not on latest version of MySQL < 8 you could use a query like
select v.id,
v.name,
m.id as model_id,
m.name,
s.qty,
p.price
from vehicles v
join models m on v.id = m.vehicle_id
join (
select *
from stocks st
where id = (
select max(id)
from stocks
where st.vehicle_id =vehicle_id
and st.model_id = model_id
)
) s
on v.id = s.vehicle_id
and m.id = s.model_id
join (
select *
from prices pr
where id = (
select max(id)
from prices
where pr.vehicle_id =vehicle_id
and pr.model_id = model_id
)
) p on v.id = p.vehicle_id
and m.id = p.model_id
DEMO
Find most "popular" follower for a specific person. The more followers someone has, the more
"popular" they are.
I need SQL query to select most popular follower of particular people.
My Table - (followers)
id | person_id | follower_person_id
1 1 2
2 1 3
3 2 1
4 2 4
5 3 1
6 3 2
7 3 4
8 4 3
For example person_id 1 has total 2 follower, person_id 2 has total 2
followers, person_id 3 has total 3 followers and person_id 4 has total
2 followers.
Therefore, person_id 3 is most popular follower for person_id 1,
person_id 1 is most popular follower for person_id 2 and so on...
Here is my query but its not working...
SELECT follower_person_id FROM followers f where f.person_id = 1 group by f.follower_person_id having max(select count(*) from followers where person_id = f.follower_person_id)
You can use the following query to get the number of followers for each person:
SELECT person_id, COUNT(*) AS cnt
FROM followers
GROUP BY person_id
Output:
person_id cnt
-------------
1 2
2 2
3 3
4 1
Using the above query as a derived table you can get the number of followers for follower for each person (sounds a bit complicated!):
SELECT t1.person_id, t1.follower_person_id, t2.cnt
FROM followers AS t1
JOIN (
SELECT person_id, COUNT(*) AS cnt
FROM followers
GROUP BY person_id
) AS t2 ON t1.follower_person_id = t2.person_id
Output:
person_id, follower_person_id, cnt
------------------------------------
1, 2, 2
1, 3, 3
2, 1, 2
2, 4, 1
3, 1, 2
3, 2, 2
3, 4, 1
4, 3, 3
Since you are looking for just a specific person, you can use a WHERE clause in the above query:
SELECT t1.person_id, t1.follower_person_id, t2.cnt
FROM followers AS t1
JOIN (
SELECT person_id, COUNT(*) AS cnt
FROM followers
GROUP BY person_id
) AS t2 ON t1.follower_person_id = t2.person_id
WHERE t1.person_id = 1
ORDER BY t2.cnt DESC LIMIT 1
ORDER BY with LIMIT will give you the most popular person the specific person is following.
Output:
person_id, follower_person_id, cnt
-----------------------------------
1, 3, 3
Note: You can generalize the output of the second query using variables to get the most popular person each person follows (this is a greatest-per-group problem).
could you be looking for something like
SELECT person_id,COUNT(person_id) as followerCount FROM followers
GROUP BY person_id ORDER BY COUNT(person_id) DESC;
This will arbitrarily pick one of the most popular followers if there is a tie for a single person, but it does give the desired result.
SELECT
person_id,
(
SELECT
_f.follower_person_id
FROM
followers _f
WHERE
_f.person_id = f.person_id
GROUP BY
_f.follower_person_id
ORDER BY
COUNT( _f.follower_person_id ) DESC
LIMIT 1
)
FROM
followers f
GROUP BY
person_id
Working SQL Fiddle
You need to do group by person id not by follower id, should take follower_id count .
SELECT person_id ,count(follower_person_id) FROM followers f group by f.person_id
having count(follower_person_id)=(select max(f_cnt ) from
(select count(follower_person_id) f_cnt from followers group by person_id))
If there are 2 persons with same number of most popular then it will return those 2 person with same count
#Parth Can you try this smaller version, i think this is small and simple to understand
With temp as
(
select a.id, a.person_id, count(b.follower_person_id) as follower from
TableName a
inner join TableName b on a.person_id=b.follower_person_id
Group by a.person_id
)
select top 1 * from temp order by follower_person_id desc
Database structure
Table 'applicants'
id org_id team_id
1 1 1
Table 'teams'
id name
1 Test
Table 'teams_members'
id team_id user_id
1 1 1
2 1 2
Table 'users_playeraccounts'
id user_id summoner_id rank_solo
1 1 1 5
2 1 2 8
3 2 3 7
select sum(rank_solo) as rank_sum,
max(rank_solo) as highest_rank,
count(tt.id) as members,
t.name,
o.team_id
from applicants o
join teams t on o.team_id = t.id
join teams_members tt on t.id = tt.team_id
join users_playeraccounts p on tt.user_id = p.user_id
where org_id = :org
group by team_id
This offcourse gives me a result like
rank_sum highest_rank members name team_id
20 8 3 Test 1
Is there a way for me to get both the count of members with their playeraccounts aka
If 1 user has 2 it'll be 2
And also a way for me to keep it as 1 so it literally just counts the rows found in teams_members neglecting the entries in users_playeraccounts?
I want to receive both 2 and 3 as a result of my query.
You want to count the distinct number of entries in tt.id, so you can do that like this:
SELECT ... COUNT(DISTINCT tt.id) AS distinct_members ...
Rather than giving you a count of every row that has a non-null tt.id, you'll get a count of the number of unique values.
Here's my mysql table:
Table League (userid and lid are primary keys):
*userid* *lid* rank win loss streak score
---------------------------------------------------------
2 1 1 2 0 2 10
2 3 2 1 1 1 5
5 1 2 1 1 1 5
I'm trying to select the users with the top score only once. For example since userid 2 is in league (lid) 1 and 3, only his top score will be selected in the query. So in that case the row with score 10 would be selected since that's the users top score from both league 1 and 3. The row with lid 3 will not be selected.
So the query results should look like this:
userid lid rank win loss streak score
---------------------------------------------------------
2 1 1 2 0 2 10
5 1 2 1 1 1 5
As you can see userid 2 with lid 3 was not in the result because the score 10 from lid 1 was grater than score 5 from league 3. Any ideas?
SELECT l.userid, u.username, l.lid, l.rank, l.win, l.loss, l.streak, l.score
FROM (SELECT userid, MAX(score) AS MaxScore
FROM League
GROUP BY userid) q
INNER JOIN League l
ON q.userid = l.userid
AND q.MaxScore = l.score
INNER JOIN users u
ON l.userid = u.userid
SELECT *
FROM table t1
WHERE t1.score = (SELECT MAX(t2.score)
FROM table t2
WHERE t1.userid = t2.userid)
This will display ties, don't know if you want those or not.
Here the simplest solution:
SELECT *
FROM League t1
WHERE
t1.lig = (SELECT t2.lig
FROM League t2
WHERE t2.userid = t1.userid
ORDER BY score desc
LIMIT 1
)
I have four tables: groups, users, votes, follows.
The structures of these tables are
groups
g_id g_title g_content
1 t1 content1
2 t2 content2
users
u_id u_groupid
1 1
2 1
3 2
4 2
5 2
votes
v_id v_userid v_groupid v_votes
1 1 1 1
2 1 2 1
3 2 2 1
4 3 2 1
5 3 1 1
follows
f_id f_userid f_groupid
1 1 1
2 2 1
3 2 2
4 3 1
5 3 2
The groups table records the basic information of a "group".
The users table keeps the relationship between users and groups, that is, if the user A belongs to groups B, then there will be a record in the user table.
The votes table means the supportive attitude that a user holds to a group.
If user A is interested in group A, then add a entry into the Follows table.
Now my problem is how to write one select statement to query the number of users, the number of votes and the number of followers of each group.
I want the query result likes this
g_id num_users unm_votes num_followers
1 2 2 3
2 3 3 2
By the way, my database is Mysql 5.0.51b.
If you want in 1 query, something like this will help you
SELECT g_id,
d1.num_users,
d2.unm_votes,
d3.num_followers
FROM groups gg
LEFT JOIN (SELECT g_id,
COUNT(u.u_id) AS num_users
FROM groups g
LEFT JOIN users u
ON u.u_groupid = g.g_id
GROUP BY g_id) d1
ON d1.g_id = gg.g_id
LEFT JOIN (SELECT g_id,
COUNT(v.v_userid) AS unm_votes
FROM groups g
LEFT JOIN votes v
ON v.v_groupid = g.g_id
GROUP BY g_id) d2
ON d2.g_id = gg.g_id
LEFT JOIN (SELECT g_id,
COUNT(f.f_userid) AS num_followers
FROM groups g
LEFT JOIN follows f
ON f.f_groupid = g.g_id
GROUP BY g_id) d3
ON d3.g_id = gg.g_id
GROUP BY gg.g_id
For the user count by group:
select g_id,count(u.uid) user_count from groups g, users u
where u.groupid = g.g_id
group by g_id
May want to read up on group by.