Mysql Joining four tables - mysql

I've been having trouble linking these tables together:
Table 1: Matches
ID
Name
Date
1
Adam vs Lance
2021-09-2021
2
Bex vs Adam vs Erica
2021-08-2021
3
Craig vs Bree
2021-07-2021
4
Danielle vs Alan
2021-06-2021
5
Erica vs Zoe vs AJ
2021-05-2021
6
Bree vs Erica
2021-04-2021
7
Bree vs Lance
2021-03-2021
8
Bree vs Lance vs Zoe
2021-02-2021
Table 2: Winners:
ID
Name
Match ID
IDNum
1
Adam
1
1
2
Bex
2
3
3
Danielle
4
7
4
Zoe
5
9
5
Erica
6
4
6
Bree
7
5
7
Bree
8
5
Table 3: Losers:
ID
Name
Match ID
IDNum
1
Lance
1
2
2
Adam
2
1
3
Erica
2
4
4
Alan
4
8
5
AJ
5
10
6
Erica
5
4
7
Bree
6
5
8
Lance
7
2
9
Lance
8
2
10
Zoe
8
9
Table 3: Draws:
ID
Name
Match ID
IDNum
1
Craig
3
6
2
Bree
3
5
Table 4: Players
ID
Name
Gender
1
Adam
M
2
Lance
M
3
Bex
F
4
Erica
F
5
Bree
F
6
Craig
M
7
Danielle
F
8
Alan
M
9
Zoe
F
10
AJ
F
The query I've been trying is to look up all matches with Bree in them and order them by date.
Table 5: Output:
Match ID
3
6
7
8
Draw: Match ID: 3
Los: Match ID: 6
Win: Match ID: 7
Win: Match ID: 8
When I try to inner join wins & losses against the Match table it works but the second I include the draws it does not return anything.
If I try just returning draws it works but then inner joining either losses or wins causes 0 results.
Can anyone help me with the code that'll work?
Query I'm trying:
SELECT Matches.ID AS MatchID, Winners.Name
FROM Matches
inner JOIN Draws
ON Matches.ID = Draws.MatchID
inner JOIN Winners
ON Matches.ID = Winners.MatchID
inner JOIN Losers
ON Matches.ID = Losers.Match ID
and (Winners.winner_id_num = 5
OR
Losers.type_id_num = 5
OR
Draws.IDNum = 5
)
GROUP BY match_id_num;

I would recommend you to use UNION between the 3 tables with results and join the output with the Matches table.
SELECT r.Result, r.IDMatch FROM (
SELECT *, 'Win' as Result FROM Winners WHERE IDNum = 5
UNION
SELECT *, 'Los' as Result FROM Losers WHERE IDNum = 5
UNION
SELECT *, 'Draw' as Result FROM Draws WHERE IDNum = 5
) AS r
INNER JOIN Matches AS m ON m.ID = r.IDMatch
ORDER BY m.Date DESC
The output would be:
Draw 3
Los 6
Win 7
Win 8

Related

calculating the average of marks from the beginning to this record

i have a table named test with the below structure like this
id mark join_id
1 5 1
2 4 1
3 9 1
4 5 2
5 7 2
6 12 2
i want to write a query that can get me the average of the marks from the beginning record to this record with the desired result as below
id mark join_id avg_of_previous_marks
1 5 1 5
2 4 1 4.5
3 9 1 6
4 5 2 5.75
5 7 2 6
6 12 2 7
i wrote this query but it doesn't seem to work correctly
SELECT test.id, test.mark, test.join_id, test_avg.avg_of_previous_marks FROM test
LEFT JOIN (SELECT id, join_id, AVG(mark) as avg_of_previous_marks FROM test GROUP BY
join_id) test_avg
ON test_avg.join_id = test.join_id AND test_avg.id <= test.id
and it gives this resault
id mark join_id avg_of_previous_marks
1 5 1 6
2 4 1 6
3 9 1 6
4 5 2 8
5 7 2 8
6 12 2 8
Its a simple running total that you need.
select id,mark,join_id, avg(mark) over (order by id) avg_of_previous_marks from test_avg ;
fiddle here

MySQL Query results AND

What I have is 3 tables: fruits, categories and fruit_category
fruits:
fruit_id | fruit_name
1 apple
2 orange
3 mango
4 banana
5 lanzones
6 pineapple
fruit_category:
fruit_id | cat_id
1 1
2 9
3 7
4 7
5 8
6 9
1 9
2 7
3 9
4 1
5 3
6 5
categories
cat_id | cat_name
1 one
2 two
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine
When I execute a query looking for fruits that are either in categories 7 or 9 I get the correct results
fruit_name
apple
orange
mango
banana
pineapple
But when I use the AND operator, I always get 0 results. Below is my query for AND (same for OR)
SELECT `o`.`fruit_name`
FROM `fruits` AS `o`
JOIN `fruit_category` AS `oc`
ON `o`.`fruit_id` = `oc`.`fruit_id`
JOIN `categories` AS `c`
ON `c`.`cat_id` = `oc`.`cat_id`
WHERE `oc`.`cat_id` = 7
AND `oc`.`cat_id` = 9
You should use logical or (one value can't be equal to two unequal values at the same time), represented by in here:
where `oc`.`cat_id` in ( 7, 9)
Which is equivalent to:
where `oc`.`cat_id` = 7 or `oc`.`cat_id` = 9
If you want to ensure, that fruit_name is in both categories, you should use group by and having clauses after the where (that is represented above, with or):
group by `o`.`fruit_name`
having count(distinct `oc`.`cat_id`) = 2
SELECT
o.fruit_name
FROM
fruits as o
JOIN
fruit_category as oc
ON
o.fruit_id = oc.fruit_id
JOIN
categories as c
ON
c.cat_id = oc.cat_id
WHERE
oc.cat_id IN (7,9)
GROUP BY
o.fruit_name
HAVING
COUNT(oc.cat_id) = 2

ROW COUNT in MYSQL

In mysql, I got table "a" as follow
ID USERNAME SUBJECT_ID
1 ALAN 1
2 ALAN 2
3 ALAN 3
4 ALAN 4
5 ALAN 5
6 JOHN 6
7 ALAN 7
8 JOHN 8
9 ALAN 9
I just want to know username = ALAN takes how many subject and how generate a new column to C become
ID USERNAME SUBJECT_ID C
1 ALAN 1 1
2 ALAN 2 2
3 ALAN 3 3
4 ALAN 4 4
5 ALAN 5 5
7 ALAN 7 6
9 ALAN 9 7
The column is group by USERNAME and generate the row count.How should I query and generate C field?
The query I have tried, but I don't know how to generate "C"
SELECT ID,USERNAME,SUBJECT_ID,C FROM a WHERE USERNAME = "ALAN" GROUP BY SUBJECT_ID
Please help, thanks.
You can use Row number in mysql, this way:
SELECT T1.*,#rownum := #rownum+1 as C
FROM TableName T1,(SELECT #rownum := 0) r
WHERE T1.Username LIKE '%ALAN%'
Result:
ID USERNAME SUBJECT_ID C
-----------------------------
1 ALAN 1 1
2 ALAN 2 2
3 ALAN 3 3
4 ALAN 4 4
5 ALAN 5 5
7 ALAN 7 6
9 ALAN 9 7
Example in SQL Fiddle.

Retrieve from multiple tables while only allowing distinct results for one column

I am trying to select from three tables, Regions, Players, and regionplayer. and order the results by region name, and then by when the players attached to that region where last seen. I would really like it so that i only return one result for each region, with the player who hasn't been seen the longest.
SQL.
SELECT RegionName.*, RegionPlayer.*, Players.*
FROM RegionName
JOIN RegionPlayer
ON RegionPlayer.Regionkey = RegionName.Key
JOIN Players
ON Players.Key = RegionPlayer.Playerkey
GROUP BY RegionName.Name, Players.Seen DESC
some table data.
RegionName
key Name
1 regionone
2 regiontwo
3 regionthree
4 regionfouor
5 regionfive
Players
Key Name Seen
1 jack 2014-03-21 12:43:46
2 joe 2014-03-26 12:43:46
3 bob 2014-03-20 12:43:46
4 bill 2014-03-19 12:43:46
5 dave 2014-03-17 12:43:46
6 tina 2014-03-28 12:43:46
7 tony 2014-03-29 12:43:46
8 george 2014-03-15 12:43:46
9 sam 2014-03-18 12:43:46
10 frank 2014-03-18 12:43:46
RegionPlayer
key Regionkey PlayerKey
1 1 1
2 1 4
3 1 5
4 2 1
5 2 4
6 3 6
7 3 7
8 4 1
9 4 8
10 4 7
11 5 3
I take your statement, at first the part before GROUP BY
SELECT RegionName.*, RegionPlayer.*, Players.*
FROM RegionName
JOIN RegionPlayer
ON RegionPlayer.Regionkey = RegionName.Key
JOIN Players
ON Players.Key = RegionPlayer.Playerkey
and add
WHERE Players.Seen = (
SELECT MIN(Players2.Seen)
FROM RegionName as RegionName2
JOIN RegionPlayer as RegionPlayer2
ON RegionPlayer2.Regionkey = RegionName2.Key
JOIN Players as Players2
ON Players2.Key = RegionPlayer2.Playerkey
WHERE RegionName2.Key = RegionName.Key
)
and then GROUP BY from your statement
GROUP BY RegionName.Name, Players.Seen DESC
The subselect returns the minimum date SEEN from PLAYERS for current region.

update statement with aggregate function

Good day everyone..!:-)
I have this table tab where totalUsed is equal to the sum of all used values referenced to name
cid name used total
1 a 1 1
2 a 3 4
3 a 6 10
4 b 3 3
5 b 7 10
6 b 10 0
7 a 5 0
i have this code but it only copy totalUsed's adjacent used value
UPDATE tab
SET totalUsed=
(
SELECT SUM(used)
)
cid name used total
1 a 1 1
2 a 3 3
3 a 6 6
4 b 3 3
5 b 7 7
6 b 10 10
7 a 5 5
if used is set as 10 for cid 6, totalUsed should be 20
and for cid 7 it should be 15.
how to do it in mysql?
it should look like this.
cid name used total
1 a 1 1
2 a 3 4
3 a 6 10
4 b 3 3
5 b 7 10
6 b 10 20
7 a 5 15
thanks for help
:-)
In most dialects of SQL, you can do this using an update with a correlated subquery:
UPDATE tab
SET totalUsed = (SELECT SUM(used)
from tab tab2
where tab2.name = tab.name and
tab2.cid <= tab.cid
);
EDIT:
The above will not work in MySQL. You can do this instead:
UPDATE tab join
(select tab2.cid,
(SELECT SUM(used)
from tab tab3
where tab3.name = tab2.name and
tab3.cid <= tab2.cid
) as cum_used
from tab tab2
) tab2
on tab.cid = tab2.cid
SET tab.totalUsed = tab2.cum_used;