简体   繁体   中英

Creating Medalist MySQL view from a table

I need a help to create a view in MySQL.

I have a table in the name of competitions like below:

+---------+-----+-----+-----+
|id| name |rank1|rank2|rank3| 
+--+------+-----+-----+-----+
| 1| cmpt1| 4   | 3   | 9   |
| 2| cmpt2| 3   | 7   | 8   |
| 3| cmpt3| 4   | 1   | 2   |
| 4| cmpt4| 5   | 8   | 4   |
| 5| cmpt5| 9   | 3   | 2   |
| 6| cmpt6| 1   | 8   | 2   |
+--+------+-----+-----+-----+

the rank1,2,3 values refer to the player id who has such rank at the end of that competition.

Now I want to create a MySQL view to show each player's total medals. Rank 1, 2, and 3 received gold, silver, and bronze medal respectively.

The output of the view will be like following table:

+------+------------+-------------+-------------+
|player| gold_medals|silver_medals|bronze_medals| 
+------+------------+-------------+-------------+
| 1    |     4      |     7       |     1       |
| 2    |     7      |     0       |     9       |
| 3    |     1      |     4       |     6       |
| 4    |     0      |     2       |     8       |
| 5    |     2      |     8       |     0       |
| 6    |     3      |     1       |     1       |
+------+------------+-------------+-------------+

Thanks in advance

I assumed you have another table for list players :

 select p.playerid , count(case when playerid = rank1 then 1 end) gold_medals , count(case when playerid = rank2 then 1 end) silver_medals , count(case when playerid = rank3 then 1 end) bronze_medals from players p left join ranks r on p.playerid in (rank1, rank2, rank3) group by p.playerid
\nplayerid | gold_medals |  silver_medals | bronze_medals\n-------: |  ----------: |  ------------: |  ------------: \n       1 |  1 |  1 |  0 \n       2 |  0 |  0 |  3 \n       3 |  1 |  2 |  0 \n       4 |  2 |  0 |  1 \n       5 |  1 |  0 |  0 \n       6 |  0 |  0 |  0 \n       7 |  0 |  1 |  0 \n       8 |  0 |  2 |  1 \n       9 |  1 |  0 |  1 \n

db<>fiddle here

You can unpivot and aggregate:

select playerid,
       sum(ranking = 1) as num_gold,
       sum(ranking = 2) as num_silver,
       sum(ranking = 3) as num_bronze
from ((select rank1 as playerid, 1 as ranking
       from ranks
      ) union all
      (select rank2, 2 as ranking
       from ranks
      ) union all
      (select rank3, 3 as ranking
       from ranks
      ) 
     ) p
group by playerid;

Note: This only includes players who have a ranking. Your question doesn't include a source of all players, so that seems sufficient.

Here is a db<>fiddle.

Note that older versions of MySQL (pre-5.7 I think) don't support subqueries in the FROM clause of views. Happily that restriction is no longer in force.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM