Sql join 4 tables count rows - mysql

I have 4 tables in similar form. Structures of these tables are like:
id team_id position_id country_id
1 1 1 3
2 1 1 3
3 2 2 3
4 3 3 3
I can count rows of one table with:
SELECT count(position_id) as count1, position_id
FROM players1
where country_id = 3
group by position_id;
Getting result as:
position_id count1
1 54
2 41
3 39
4 32
I want join 4 tables and want to get a result like:
position_id count1 count2 count3 count4
1 54 42 51 61
2 41 40 49 59
3 39 29 44 50
4 32 21 37 47
Can you help me write this sql?

As I have understand you question. Execute this Mysql query.
SELECT
d1.position_id AS Positions_Id,
d1.count1 AS count1,
d2.count1 AS count2,
d3.count1 AS count3,
d4.count1 AS count4
FROM (
SELECT position_id, COUNT(position_id) AS count1
FROM players1
WHERE country_id=3
GROUP BY position_id) AS d1
LEFT JOIN (
SELECT position_id, COUNT(position_id) AS count1
FROM players2
WHERE country_id=3
GROUP BY position_id
) AS d2 ON d2.position_id = d1.position_id
LEFT JOIN (
SELECT position_id, COUNT(position_id) AS count1
FROM players3
WHERE country_id=3
GROUP BY position_id
) AS d3 ON d3.position_id = d1.position_id
LEFT JOIN (
SELECT position_id, COUNT(position_id) AS count1
FROM players4
WHERE country_id=3
GROUP BY position_id
) AS d4 ON d4.position_id = d1.position_id

Related

sql query to count votes, groub by candidate_id, position_id

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

mysql - How do we get the sum of the values on two tables?

I have two tables
table: a
---------------------
id amount status
---------------------
4031 3000 1
4032 4000 1
4033 5000 1
4034 6000 1
4035 7000 1
4036 8000 0
table: s
--------------
id a_id b_id
--------------
1 4031 20
2 4031 21
3 4032 23
4 4032 24
5 4033 25
6 4033 26
7 4034 21
8 4034 20
9 4035 25
10 4035 29
11 4036 21
12 4036 20
How do we get the sum of the a.amount where have ( b_id = 20 AND b_id = 21) AND a.status = 1?
The answer should be 9000.
SELECT SUM(amount) FROM (
JOIN s ON a.id = s.id
WHERE STATUS =1
AND (b_id = 20 OR b_id = 21) GROUP BY a.id
) AS amounts
total : 9000
In the case you can add several times the same amount, I guess this should work without join:
SELECT SUM(amount) AS total
FROM `a`, `s`
WHERE a_id = a.id AND (b_id = 20 OR b_id = 21) AND status = 1
total : 18000
Try this:
select sum(a.amount)
from a
join b on a.id = b.a_id
where b.b_id IN ( 20, 21 ) and a.status = 1
You can get the answer using a subquery:
SELECT SUM(a.amount)
FROM a
WHERE a.status=1 AND
EXISTS (SELECT 1
FROM s
WHERE s.a_id=a.id AND s.b_id in (20,21));
There is no need to group the data as we want the global sum of the amounts selected.
SELECT SUM(a.amount)
FROM a
WHERE a.status=1 AND
EXISTS (SELECT 1
FROM s
WHERE s.a_id=a.id AND s.b_id=20) AND
EXISTS (SELECT 1
FROM s
WHERE s.a_id=a.id AND s.b_id=21) ;

mysql select max group by id

good evening,
i have a table:
A B C
45 1 1
22 2 1
40 3 1
43 1 2
21 2 2
61 3 2
49 4 2
60 5 2
76 1 3
41 2 3
57 3 3
i find max(A) from max(B) group by C. The result should be 60 - max number in A from last row in B from each group (C)
Thank you for your help
If i understand correctly your question you could use an inner join on select max(b):
select max(A)
from my_table m
inner join (
select C,
max(B) act_B
from my_table
group by C
) t on t.act_B = m.B and t.c = m.c

select a column with the highest id which have common fields

i have a table named iview:
gpreq_id a_id m_id rcv_qty
1 100 4 0
2 100 4 1
3 100 5 4
4 101 4 1
5 101 4 10
6 101 4 1
how can i select this that the m_id in the a_id's has the highest gpreq_id?
like:
gpreq_id a_id m_id rcv_qty
2 100 4 1
3 100 5 4
6 101 4 1
First find max value for each a_id, m_id pair and then join to iview:
select i.*
from iview as i
inner join (
select a_id, m_id, max(gpreq_id) as max_gpreq_id
from iview
group by a_id, m_id
) as mi on (mi.max_gpreq_id = i.pgreq_ie)
Try something like
SELECT i1.*
FROM iview as i1
WHERE i1.gpreq_id IN (SELECT MAX(gpreq_id)
FROM iview as i2
GROUP BY i2.a_id, i2.m_id)
Here is the SQL FIDDLE

select data based on multiple criteria (cloest value)

I am using MySQL. I'm trying to build something and just can't find a solution to a problem.
I am selecting a value from the lookup table based on my table as shown in the below example.
Select Criteria:
my.id<>l.id AND my.route1=l.route1 AND my.route2=l.route2 AND my.utc=l.utc
where my.stime is closest or same as l.stime
ex) my.id=2's col should get the l.id=1, l.etime=7777 since my.id<>l.id and the rest are the same.
ex) my,id=5's col has options l.id=3, l.etime=9999 and l.id=4, l.etime=7979 since my.id<>l.id, my.route=l.route, my.utc=l.utc. Yet, since my.stime=2220 is closer to l.stime=2222 than l.stime=3333 , l.id=3, l.etime=9999 will be chosen.
ex) my,id=6's col example is to select either value if "closest" is the same.
ex) my,id=7's col example is to return NULL when the criteria is not met.
Table: lookup (l.)
id route1 route2 utc stime etime
---|--------|--------|-----|-------|------
1 11 22 111 1111 7777
2 11 22 111 1111 8888
3 22 33 222 2222 9999
4 22 33 222 3333 7979
5 22 33 222 3335 8989
Table: my (my.) | result
id route1 route2 utc stime | l.id l.etime
---|--------|--------|-----|------- |-------|----------|
2 11 22 111 1111 | 1 7777
5 22 33 222 2220 | 3 9999
6 22 33 222 3334 | 4or5 7979or8989
7 22 33 999 9999 | null null
A new table should be created where the result is appended to the last col of my.
Any help is appreciated. Thanks in advance.
This solution is a bit convoluted, but it's a starting point.
First, let's create an auxiliary table:
CREATE TEMP TABLE temp AS
SELECT m.id mid, l.id lid, ABS(l.stime-m.stime) timediff
FROM my m JOIN lookup l
WHERE m.route1 = l.route1 AND m.route2 = l.route2 AND
m.utc = l.utc AND m.id <> l.id;
From this table we can get the minimum timediff for each my.id:
SELECT mid, min(timediff) mtimediff FROM temp GROUP BY mid
Result:
mid mtimediff
---------- ----------
2 0
5 2
6 1
Now we can find which rows in lookup have this stime difference, and choose the smallest id:
SELECT t.mid mid, min(lid) lid
FROM temp t JOIN (
SELECT mid, min(timediff) mtimediff FROM temp GROUP BY mid
) mt ON t.mid = mt.mid AND t.timediff = mt.mtimediff
GROUP BY t.mid
This is the result:
mid lid
---------- ----------
2 1
5 3
6 4
And finally we use those ids to extract the data from the tables:
SELECT m.id, m.route1, m.route2, m.utc, m.stime, l.id, l.etime
FROM my m JOIN lookup l JOIN (
SELECT t.mid mid, min(lid) lid
FROM temp t JOIN (
SELECT mid, min(timediff) mtimediff FROM temp GROUP BY mid
) mt ON t.mid = mt.mid AND t.timediff = mt.mtimediff
GROUP BY t.mid
) ON m.id = mid AND l.id = lid;
Giving:
id route1 route2 utc stime id etime
---------- ---------- ---------- ---------- ---------- ---------- ----------
2 11 22 111 1111 1 7777
5 22 33 222 2220 3 9999
6 22 33 222 3334 4 7979