I am (very) new to MySQL. Forgive my lack of knowledge....
I am working on a hockey stat database where I need to add all the assists and all the goals together to get "total points". I have two queries already figured out, but I am not able to figure out how to sum the two.
Here are the queries:
select player_id, count(*)
from(select * from 1st_assists
union
select * from 2nd_assists) as tem
join players on tem.fk_player_id=players.player_id
group by fk_player_id
order by count(*) desc
select player_id, count(*)
from goals_for
join shots_for on goals_for.fk_shot_for_id=shots_for.shot_for_id
join players on shots_for.fk_player_id=players.player_id
group by player_id
order by count(*) desc;
how do I combine these two queries into one and get the total of both counts?
Here are the results of each of the queries
Total Assists
player_id count(*)
79 24
55 22
45 17
90 16
40 15
65 15
37 13
1 13
20 11
84 11
64 10
27 9
93 7
8 5
24 3
57 1
Goals
player_id count(*)
90 38
37 28
40 19
55 13
45 11
1 8
24 8
20 8
84 8
27 6
8 5
79 4
65 4
93 1
64 1
It is untested, but can you, please, try this:
select p.player_first_name, p.player_last_name, (count1+count2) as total_count
from
(select player_id, count(*) count1
from(select * from 1st_assists
union
select * from 2nd_assists) as tem
join players on tem.fk_player_id=players.player_id
group by fk_player_id
order by count(*) desc) q1
left join
(select player_id, count(*) count2
from goals_for
join shots_for on goals_for.fk_shot_for_id=shots_for.shot_for_id
join players on shots_for.fk_player_id=players.player_id
group by player_id) q2
ON q1.player_id=q2.player_id
left join player p ON q1.player_id=p.player_id
order by (count1+count2) desc;
Related
I have a high scores table that is slightly more complicated because scores are tracked in rounds (round 1, round 2, round 3, etc.). Sample table:
scoreID
roundID
userID
score
1
1
2
25
2
1
3
12
3
1
4
14
4
1
5
6
5
2
2
39
6
2
3
23
7
2
4
13
8
2
5
26
There can be many more rounds, and many more users.
I would like to pull the top 3 user scores from each round. My select statement at the moment looks like this:
select `scores`.`score`, `users`.`username`, `scores`.`roundID`
FROM `scores`
INNER JOIN `users` on `users`.`user_id` = `scores`.`userID`
ORDER BY `scores`.`score` DESC LIMIT 3;
However, this returns a result like so:
score
username
roundID
39
joey
2
26
bubba
2
25
george
1
when what I want is the top 3 scores per round:
score
username
roundID
25
george
1
14
bubba
1
12
joey
1
39
george
2
26
homey
2
23
joey
2
How do I select the top 3 scores in each round so my result mirrors the table immediately above?
You would do this like:
select score, username, roundID
from (
select
score, userID, roundID,
rank() over (partition by roundID order by score desc) score_rank
from score
) ranked_scores
inner join users on users.user_id = ranked_scores.userID
where score_rank <= 3
order by roundID, score, username
table VOTES
id
voters_id
candidate_id
positions_id
1
xxx
18
6
2
xxx
18
6
3
xxx
18
6
4
xxx
18
6
5
xxx
19
6
6
xxx
19
6
7
xxx
22
20
8
xxx
22
20
table POSITIONS
id
title
6
president
20
mayor
table candidates
id
name
18
mark
19
john
22
eddie
I HAVE THESE THEERE TABLES, I NEED A QUERY FOR THIS OUTPUT
total_votes
candidate_id
candidate_name
position_id
position_name
4
18
mark
6
president
2
19
mark
6
president
2
22
eddie
20
mayor
Use:
select v.total_votes,
v.candidate_id,
c.name as candidate_name,
v.position_id ,
p.title as position_name
from (select COUNT(*) as total_votes,
candidate_id,
position_id
from votes
GROUP BY candidate_id, position_id
) as v
INNER JOIN positions p on v.position_id=p.id
INNER JOIN candidates c on c.id=v.candidate_id ;
Result:
total_votes candidate_id candidate_name position_id position_name
4 18 mark 6 president
2 19 john 6 president
2 22 eddie 20 mayor
Note. Aggregation always comes after the join, that's why you need to do the aggregation on a subquery
https://dbfiddle.uk/7q9GUm0y
can i ask, if i would add the percentage, counting the SUM of total
votes, on the votes obteined from a single candidate, how should i do
it?
select v.total_votes,
round(((v.total_votes * 100) / temp.tot_voters),2) AS Percentage,
concat(round(((v.total_votes * 100) / temp.tot_voters),2),'%') AS Percentage_1,
v.candidate_id,
c.name as candidate_name,
v.position_id ,
p.title as position_name
from (select COUNT(*) as total_votes,
candidate_id,
position_id
from votes
GROUP BY candidate_id, position_id
) as v
CROSS JOIN (select count(voters_id) as tot_voters from votes) temp
INNER JOIN positions p on v.position_id=p.id
INNER JOIN candidates c on c.id=v.candidate_id ;
https://dbfiddle.uk/wBTbVVlf
There are two campaigns running campaign A and Campaign B and list of user ids participated in those two campaign is given below. Calculate the number of users based on the below conditions by writing a single query.
Participated in campaign A
Participated in campaign B
Participated in campaign A only
Participated in campaign B only
Participated in both the campaigns
Participated in either campaign A or Campaign B
Campaign A Campaign B
user_id user_id
91 62
27 11
58 16
50 92
64 17
65 71
54 12
98 37
78 93
24 58
31 54
73 94
63 85
72 30
94 32
20 1
38 48
8 99
43 45
33 46
26 39
100 29
61 49
87 73
84 81
15 88
80 70
77 33
40 55
82
42
56
95
88
I am not able to figure out how to write in single SQL query.
Assuming you have two different tables, you can use union all and aggregation:
select in_a, in_b, count(*) as num_users
from ((select user_id, 1 as in_a, 0 as in_b
from a
) union all
(select user_id, 0 as in_a, 1 as in_b
from b
)
) u
group by in_a, in_b;
This gives you all the information you need. You can use group by in_a, in_b with rollup to get all combinations.
Or, you can summarize this into one row:
select sum(in_a) as in_a, sum(in_b) as in_b,
sum(in_a * (1 - in_b)) as in_a_only,
sum(in_b * (1 - in_a)) as in_b_only,
sum(in_a * in_b) as in_ab
from ((select user_id, 1 as in_a, 0 as in_b
from a
) union all
(select user_id, 0 as in_a, 1 as in_b
from b
)
) u;
Note: These both assume that users are unique in each campaign. If not, just use select distinct or union in the subquery.
I am trying to attain the count of users that ordered at least 1 product on multiple days.
Transactions Table
usr_id|transt_id|product_id|spend| transaction_date
4 8 32 40 2020-05-08 17:54:59
4 7 31 20 2020-05-01 17:54:59
4 7 31 40 2020-05-01 17:54:59
4 6 20 30 2020-05-02 17:54:59
4 6 19 20 2020-05-02 17:54:59
4 6 18 10 2020-05-02 17:54:59
3 5 17 20 2020-05-04 17:54:59
3 5 16 10 2020-05-04 17:54:59
2 3 14 30 2020-05-04 18:54:59
2 3 13 50 2020-05-04 18:54:59
1 2 12 30 2020-05-05 20:54:59
1 2 12 40 2020-05-05 20:54:59
1 2 12 40 2020-05-04 20:54:59
1 1 11 20 2020-05-05 21:54:59
1 1 10 40 2020-05-05 21:54:59
3 4 10 60 2020-05-06 17:54:59
Through my code I have been able to reach to a point where the output is:
select user_id, count(*)
from (
select user_id, date(transaction_date)
from transactions
group by user_id, date(transaction_date)) as abc
group by user_id
having count(user_id)>1;
user_id | count
1 2
3 2
4 3
I want to write a code without writing another subquery to get the count of users having count(*)>1;
The output should be: 3.
In other words, I don't want the following code; I want to write one less subquery or a completely new query
select count(*)
from (
select user_id, count(*)
from (
select user_id, date(transaction_date)
from transactions
group by user_id, date(transaction_date)) as abc
group by user_id
having count(user_id)>1) as bcd;
The query that you already have could be written without a subquery:
select user_id, count(distinct date(transaction_date)) count
from transactions
group by user_id
having count(distinct date(transaction_date))>1;
So what you need now can be written with only 1 subquery:
select count(*) count
from (
select user_id
from transactions
group by user_id
having count(distinct date(transaction_date))>1
) t
You can get the same result with EXISTS:
select count(distinct t.user_id) count
from transactions t
where exists (
select 1
from transactions
where user_id = t.user_id and date(transaction_date) <> date(t.transaction_date)
)
See the demo.
i stack at mysql syntax where i have a table revenue with values
title_id | revenue | cost
1 | 10 | 5
2 10 5
3 10 5
4 10 5
1 20 6
2 20 6
3 20 6
4 20 6
and then i have table fund with values
title_id | interest
1 | 10
2 10
3 10
4 10
1 20
2 20
3 20
4 20
I want to join this two table using left join and rollup the values like this :
SELECT R.title_id,
R.revenue,
R.cost,
F.interest
FROM (SELECT title_id,
Sum(revenue) revenue,
Sum(cost) cost
FROM revenue
GROUP BY revenue.title_id with rollup) r
LEFT JOIN (SELECT title_id,
Sum(interest) interest
FROM fund
GROUP BY title_id with rollup) f
ON r.title_id = F.title_id;
Output :
title_id | revenue | cost | interest
1 30 11 30
2 30 11 30
3 30 11 30
4 30 11 30
Total 120 44 null
But I want the output is :
title_id | revenue | cost | interest
1 30 11 30
2 30 11 30
3 30 11 30
4 30 11 30
Total 120 44 120
is this possible ?
Thanks before
Here's the details scenario:
With Data Given:
select a.title_id, sum(revenue), sum(cost),sum(interest) from
(select a.title_id, sum(revenue) as revenue, sum(cost) as cost from
(select 1 title_id, 10 revenue , 5 cost UNION all
select 2, 10, 5 UNION all
select 3, 10, 5 UNION all
select 4, 10, 5 UNION all
select 1, 20, 6 UNION all
select 2, 20, 6 UNION all
select 3, 20, 6 UNION all
select 4, 20, 6) as a
GROUP BY title_id) as a
left JOIN
(select title_id, sum(interest) as interest from
(select 1 as title_id, 10 as interest UNION all
select 2, 10 UNION all
select 3, 10 UNION all
select 4, 10 UNION all
select 1, 20 UNION all
select 2, 20 UNION all
select 3, 20 UNION all
select 4, 20) as b
GROUP BY title_id ) as b
on a.title_id = b.title_id
GROUP BY a.title_id
with ROLLUP
result:
1 30 11 30
2 30 11 30
3 30 11 30
4 30 11 30
120 44 120
final query structure:
select a.title_id, sum(revenue), sum(cost),sum(interest) from
(select a.title_id, sum(revenue) as revenue, sum(cost) as cost from
(select * from revenue) as a
GROUP BY title_id) as a
left JOIN
(select title_id, sum(interest) as interest from
(select * from fund) as b
GROUP BY title_id ) as b
on a.title_id = b.title_id
GROUP BY a.title_id
with ROLLUP