How can I select all Countries which won more than the average number of (any) medal across all countries from the table below:
+-----------+-------------+--------+-----------------+----------------------------+-------------------------------+-----------------------------------------+---------------------------------+-------------------------+
| idRESULTS | STATUS | MEDALS | EVENTS_idEVENTS | EVENTS_ATHLETES_idATHLETES | EVENTS_ATHLETES_TEAMS_idTEAMS | EVENTS_ATHLETES_TEAMS_COUNTRY_idCOUNTRY | EVENTS_VARIOUS_SPORTS_SPORTS_ID | awarded_medals_medal-id |
+-----------+-------------+--------+-----------------+----------------------------+-------------------------------+-----------------------------------------+---------------------------------+-------------------------+
| results1 | DID-NOT-WIN | SILVER | TEN | MS | RUS-WTA | RUS | WOMENS_TENNIS | 2 |
| results1 | WON | GOLD | TEN | VW | USA-WTA | USA | WOMENS_TENNIS | 3 |
| results2 | DID-NOT-WIN | BRONZE | ATH | JG | USA-TF-MEN | USA | TRACK-AND-FIELD | 3 |
| results2 | WON | GOLD | ATH | UB | JAM-TF-MEN | JAM | TRACK-AND-FIELD | 1 |
| results3 | WON | GOLD | TEN-DOUBLE | SW | USA-WTA | USA | WOMENS_TENNIS | 3 |
| results3 | WON | GOLD | TEN-DOUBLE | VW | USA-WTA | USA | WOMENS_TENNIS | 1 |
+-----------+-------------+--------+-----------------+----------------------------+-------------------------------+-----------------------------------------+---------------------------------+-------------------------+
I am using this code :
CREATE VIEW `Countries_Athletes_who_wo_Gold` AS
select * from results where medals = 'Gold'
select EVENTS_ATHLETES_TEAMS_COUNTRY_idCOUNTRY, medals from countries_athletes_who_wo_gold
where medals > (select AVG(medals) from countries_athletes_who_wo_gold) ;
but am not getting the required output?
You first need to write a query that counts the medals for each country.
SELECT EVENTS_ATHLETES_TEAMS_COUNTRY_idCOUNTRY, COUNT(*) AS medal_count
FROM Countries_Athletes_who_wo_Gold
GROUP BY EVENTS_ATHLETES_TEAMS_COUNTRY_idCOUNTRY
Then use this as a subquery twice in your query: once to get each country's medal count, and then to get the average across all countries.
SELECT *
FROM (
SELECT EVENTS_ATHLETES_TEAMS_COUNTRY_idCOUNTRY, COUNT(*) AS medal_count
FROM Countries_Athletes_who_wo_Gold
GROUP BY EVENTS_ATHLETES_TEAMS_COUNTRY_idCOUNTRY
) AS by_country
JOIN (SELECT AVG(medal_count) AS avg_medals
FROM (SELECT EVENTS_ATHLETES_TEAMS_COUNTRY_idCOUNTRY, COUNT(*) AS medal_count
FROM Countries_Athletes_who_wo_Gold
GROUP BY EVENTS_ATHLETES_TEAMS_COUNTRY_idCOUNTRY) AS by_country
) AS all_countries
WHERE medal_count > avg_medals
DEMO
Related
I am firing a query in mysql but not getting desired output.
this is the code:
select team_name,
sum(semis.points+final.points) as final_points
from semis
inner join final on semis.sid=final.sid
inner join teams on teams.tid=semis.tid
group by semis.tid
union
select team_name,
semis.Points
from semis
inner join teams on semis.tid=teams.tid
left join final on semis.sid=final.sid
where final.sid is null;
OUTPUT:
+-----------------------+--------------+
| team_name | final_points |
+-----------------------+--------------+
| BioTech & BioChem | 7 |
| Chemistry | 7 |
| Botany & Zoology | 7 |
| Physics & Electronics | 17 |
| BCA | 19 |
| BCOM | 11 |
| Gujarati | 10 |
| English | 10 |
| Economics | 20 |
| BCOM | 3 |
| Chemistry | 3 |
| English | 3 |
+-----------------------+--------------+
and the result i want to fetch
+-----------------------+--------------+
| team_name | final_points |
+-----------------------+--------------+
| BioTech & BioChem | 7 |
| Chemistry | 10 |
| Botany & Zoology | 7 |
| Physics & Electronics | 17 |
| BCA | 19 |
| BCOM | 14 |
| Gujarati | 10 |
| English | 13 |
| Economics | 20 |
+-----------------------+--------------+
Adding last 3 values to english,bcom,chemistry increasing it by 3 and making a total of BCOM: 14, Chemistry:10 , English: 13
From the sample data you posted and the expected results it looks like you can do it without UNION, by left joining final and with coalesce() for final.points:
select team_name, sum(semis.points + coalesce(final.points, 0)) as final_points
from semis
inner join teams on teams.tid=semis.tid
left join final on semis.sid=final.sid
group by semis.tid
I have the following tables below.
athletes
+------------+-----------------+---------------+-------------------------+
| idATHLETES | ATHLETENAME | TEAMS_idTEAMS | TEAMS_COUNTRY_idCOUNTRY |
+------------+-----------------+---------------+-------------------------+
| JG | JUSTIN GATLIN | USA-TF-MEN | USA |
| MS | MARIA SHARAPOVA | RUS-WTA | RUS |
| SW | SERENA WILLIAMS | USA-WTA | USA |
| UB | USAIN BOLT | JAM-TF-MEN | JAM |
| VW | VENUS WILLIAMS | USA-WTA | USA |
+------------+-----------------+---------------+-------------------------+
EVENTS
+------------+---------------+---------------------+------------------------+----------------------------------+
| idEVENTS | EVENTNAME | ATHLETES_idATHLETES | ATHLETES_TEAMS_idTEAMS | ATHLETES_TEAMS_COUNTRY_idCOUNTRY |
+------------+---------------+---------------------+------------------------+----------------------------------+
| ATH | ATHLETICS | JG | USA-TF-MEN | USA |
| ATH | ATHLETICS | UB | JAM-TF-MEN | JAM |
| TEN | TENNIS | MS | RUS-WTA | RUS |
| TEN | TENNIS | VW | USA-WTA | USA |
| TEN-DOUBLE | TENNIS DOUBLE | SW | USA-WTA | USA |
| TEN-DOUBLE | TENNIS DOUBLE | VW | USA-WTA | USA |
+------------+---------------+---------------------+------------------------+----------------------------------+
RESULTS
+-----------+-------------+--------+-----------------+----------------------------+-------------------------------+-----------------------------------------+
| idRESULTS | STATUS | MEDALS | EVENTS_idEVENTS | EVENTS_ATHLETES_idATHLETES | EVENTS_ATHLETES_TEAMS_idTEAMS | EVENTS_ATHLETES_TEAMS_COUNTRY_idCOUNTRY |
+-----------+-------------+--------+-----------------+----------------------------+-------------------------------+-----------------------------------------+
| results1 | DID-NOT-WIN | SILVER | TEN | MS | RUS-WTA | RUS |
| results1 | WON | GOLD | TEN | VW | USA-WTA | USA |
| results2 | DID-NOT-WIN | BRONZE | ATH | JG | USA-TF-MEN | USA |
| results2 | WON | GOLD | ATH | UB | JAM-TF-MEN | JAM |
| results3 | WON | GOLD | TEN-DOUBLE | SW | USA-WTA | USA |
| results3 | WON | GOLD | TEN-DOUBLE | VW | USA-WTA | USA |
+-----------+-------------+--------+-----------------+----------------------------+-------------------------------+-----------------------------------------+
How can I get a list Athletes who participate in more than one Event
and won at least one of them
and won none of them
I have come out with this code below but this returns the wrong output ?
SELECT idATHLETES, ATHLETENAME, EVENTNAME FROM athletes
JOIN EVENTS ON idATHLETES = ATHLETES_idATHLETES
JOIN RESULTS ON events.ATHLETES_idATHLETES = RESULTS.EVENTS_ATHLETES_idATHLETES
WHERE idEVENTS >=2 AND STATUS = 'WON'
Athletes who participated in more than one Event and won at least one of them:
select a.idATHLETES as id,a.ATHLETENAME as Name,count(*) as evtCount,
SUM(CASE WHEN r.STATUS = 'WON' THEN 1 ELSE 0 END) as victoryCount
from athletes a
join EVENTS e
on e.ATHLETES_idATHLETES = a.idATHLETES and e.ATHLETES_TEAMS_idTEAMS = a.TEAMS_idTEAMS and e.ATHLETES_TEAMS_COUNTRY_idCOUNTRY = a.TEAMS_COUNTRY_idCOUNTRY
join RESULTS r
on r.EVENTS_idEVENTS=e.idEVENTS and r.EVENTS_ATHLETES_idATHLETES=e.ATHLETES_idATHLETES -- etc
group by a.idATHLETES,a.ATHLETENAME
having evtCount>1 and victoryCount>0
order by a.idATHLETES,a.ATHLETENAME;
Results:
+----+----------------+----------+--------------+
| id | Name | evtCount | victoryCount |
+----+----------------+----------+--------------+
| VW | VENUS WILLIAMS | 2 | 2 |
+----+----------------+----------+--------------+
Athletes who participated in more than one Event and won none:
select a.idATHLETES as id,a.ATHLETENAME as Name,count(*) as evtCount,
SUM(CASE WHEN r.STATUS = 'WON' THEN 1 ELSE 0 END) as victoryCount
from athletes a
join EVENTS e
on e.ATHLETES_idATHLETES = a.idATHLETES and e.ATHLETES_TEAMS_idTEAMS = a.TEAMS_idTEAMS and e.ATHLETES_TEAMS_COUNTRY_idCOUNTRY = a.TEAMS_COUNTRY_idCOUNTRY
join RESULTS r
on r.EVENTS_idEVENTS=e.idEVENTS and r.EVENTS_ATHLETES_idATHLETES=e.ATHLETES_idATHLETES -- etc
group by a.idATHLETES,a.ATHLETENAME
having evtCount>1 and victoryCount=0
order by a.idATHLETES,a.ATHLETENAME;
Results:
no rows returned, you lack data for that
Notes
This is just a group by with having, and conditional aggregation (plus really messed up column names) :p
You can use having to get the records where there are at least two events and status = 'won' at least once.
SELECT idATHLETES, ATHLETENAME, EVENTNAME FROM athletes
JOIN EVENTS ON idATHLETES = ATHLETES_idATHLETES
JOIN RESULTS ON events.ATHLETES_idATHLETES = RESULTS.EVENTS_ATHLETES_idATHLETES AND RESULTS.Status = 'WON'
HAVING COUNT(idEVENTS) >=2 AND COUNT(STATUS) >= 1
I have got these 3 tables below, i want to list all athletes who won Gold
Athletes
+------------+-----------------+
| athletesID | athletesName |
+------------+-----------------+
| jg | justin gatlin |
| ms | maria sharapova |
| ub | usain bolt |
| vw | venus williams |
+------------+-----------------+
events
+---------+-----------+---------------------+
| eventID | eventName | athletes_athletesID |
+---------+-----------+---------------------+
| ev1 | tennis | ms |
| ev1 | tennis | vw |
| ev2 | mens 100m | jg |
| ev2 | mens 100m | ub |
+---------+-----------+---------------------+
results
+-----------+--------+----------------+----------------------------+
| resultsID | Medal | events_eventID | events_athletes_athletesID |
+-----------+--------+----------------+----------------------------+
| results1 | silver | ev1 | ms |
| results1 | Gold | ev1 | vw |
| results2 | silver | ev2 | jg |
| results2 | Gold | ev2 | ub |
+-----------+--------+----------------+----------------------------+
I have used this code below so far but this lists all the silver medalists as having won Gold
SELECT
athletesID, athletesName, medal
FROM
myoly.athletes
JOIN
myoly.events ON athletes.athletesID = events.athletes_athletesID
JOIN
myoly.results ON myoly.events.eventID = myoly.results.events_eventID
WHERE
medal = 'gold';
How can I list all athletes who won Gold only ?
SELECT
a.athletesID,
a.athletesName,
r.medal
FROM results r
LEFT JOIN athletes a
ON a.athletesID = r.events_athletes_athletesID
WHERE r.medal = 'Gold';
If you remove your WHERE medal = 'gold' and look at your results, it should give you a clue about the problem. This is often the best way to troubleshoot.
Anyway, you need to join results to athletes on athleteID instead of eventID. This is because you're concerned with which athletes won gold not which events had a gold medal.
SELECT a.athletesID,
a.athletesName,
r.medal
FROM athletes a
INNER JOIN results r ON a.athletesID = r.events_athletes_athletesID
WHERE r.medal = 'Gold'
I geather prices for products in different online store which are in United States (us), United Kingdom (uk) and etc. and hold it in one mysql TABLE (com) in local currency.
For example, for United States price in US Dollar, for United Kingdom - in GB pound.
TABLE com
---------------------------------------------------------------------------------------
| AUTO_INC | COUNTER | ID | CONC | VOLUME | PRICE | SHOP | DATE_G | COUNTRY |
|----------|---------|------|-----------|--------|-------|-----------|--------|---------|
| 115124 | 76720 | 2399 | prod_name | 13 | 34.23 | store1.us | 3 | us |
| 115186 | 50952 | 2399 | prod_name | 13 | 36 | store2.us | 3 | us |
| 115187 | 45828 | 2399 | prod_name | 13 | 37.44 | store3.us | 3 | us |
| 116448 | 73419 | 2399 | prod_name | 11.6 | 48 | store4.us | 3 | us |
| 116449 | 73421 | 2399 | prod_name | 13 | 65.5 | store4.us | 3 | us |
| 133334 | 22154 | 2399 | prod_name | 13 | 36.95 | store5.us | 4 | us |
| 133386 | 31646 | 2399 | prod_name | 13 | 37.44 | store3.us | 4 | us |
| 134828 | 54667 | 2399 | prod_name | 11.6 | 48 | store4.us | 4 | us |
| 134929 | 54670 | 2399 | prod_name | 13 | 65.5 | store4.us | 4 | us |
| 133337 | 22155 | 2399 | prod_name | 13 | 26.95 | store1.uk | 4 | uk |
| 133387 | 31647 | 2399 | prod_name | 13 | 17.44 | store2.uk | 4 | uk |
| 134829 | 54668 | 2399 | prod_name | 11.6 | 30 | store3.uk | 4 | uk |
| 134830 | 54671 | 2399 | prod_name | 13 | 45.5 | store4.uk | 4 | uk |
---------------------------------------------------------------------------------------
To convert prices from local currencies to US dollar I have created TABLE my_currency
TABLE my_currency
--------------------------------------
| AUTO_INC | DOMAIN | EX_RATE | DATE_G |
|----------|--------|---------|--------|
| 235 | uk | 0.6066 | 4 |
| 236 | us | 1 | 4 |
| 237 | uk | 0.6066 | 3 |
| 238 | us | 1 | 3 |
--------------------------------------
If I want to select minimum prices for us online stores (where COUNTRY = 'us'), I use the following query:
SELECT t1.* FROM com as t1
INNER JOIN (
SELECT id, conc, volume, min(price) as usd_price, date_g
FROM com
WHERE id=2399 AND date_g=4 AND country='us'
GROUP BY conc, volume) as t2
ON t1.conc=t2.conc and t1.volume=t2.volume and t1.id=t2.id and t1.price=t2.usd_price and t1.date_g=t2.date_g
ORDER BY conc DESC, volume DESC
And I get CORRECT result:
| AUTO_INC | COUNTER | ID | CONC | VOLUME | PRICE | SHOP | DATE_G | COUNTRY |
|----------|---------|------|-----------|--------|-------|-----------|--------|---------|
| 133334 | 22154 | 2399 | prod_name | 13 | 36.95 | store5.us | 4 | us |
| 134828 | 54667 | 2399 | prod_name | 11.6 | 48 | store4.us | 4 | us |
But now my goal is to select minimum price from all stores (country in ('us', 'uk')) and take into account that database holds prices in local currencies:
1. convert prices from local currencies to us dollar
2. select minimum prices in us dollar
So I tried to use the following query:
SELECT t1.auto_inc, t1.id, t1.conc, t1.volume, (t1.price / my_currency.ex_rate) as sub_price, t1.date_g
FROM com as t1
inner join my_currency
ON t1.country=my_currency.domain AND t1.date_g=my_currency.date_g
inner join (
select com.id, com.conc, com.volume, min(com.price / my_currency.ex_rate) as usd_price, com.date_g
from com
inner join my_currency
ON com.country=my_currency.domain AND com.date_g=my_currency.date_g
WHERE com.id=2399 AND com.date_g=4 AND com.country in ('us', 'uk')
GROUP BY conc, volume) as t2
on
t1.id=t2.id and
t1.conc=t2.conc and
t1.volume=t2.volume and
(t1.price / my_currency.ex_rate)=t2.usd_price and
t1.date_g=t2.date_g
ORDER BY conc DESC, volume DESC
But I get INCORRECT result:
| AUTO_INC | ID | CONC | VOLUME | SUB_PRICE | DATE_G |
|----------|------|-----------|--------|-----------|--------|
| 134828 | 2399 | prod_name | 11.6 | 48 | 4 |
CORRECT result is:
| AUTO_INC | ID | CONC | VOLUME | SUB_PRICE | DATE_G |
|----------|------|-----------|--------|-----------|--------|
| 134828 | 2399 | prod_name | 11.6 | 48 | 4 |
|----------|------|-----------|--------|-----------|--------|
| 133387 | 2399 | prod_name | 13 | 28.750412 | 4 |
Does anybody have any ideas?
sqlfiddle.com
The problem is the join on the calculated decimal value. The following works:
SELECT t1.auto_inc, t1.id, t1.conc, t1.volume,
(t1.price / my_currency.ex_rate) as sub_price, t1.date_g
FROM com as t1 inner join
my_currency
ON t1.country = my_currency.domain AND t1.date_g = my_currency.date_g
inner join
(select com.id, com.conc, com.volume, min(com.price / my_currency.ex_rate) as usd_price, com.date_g
from com inner join
my_currency
ON com.country = my_currency.domain AND
com.date_g = my_currency.date_g
WHERE com.id=2399 AND com.date_g = 4 AND
com.country in ('us', 'uk')
GROUP BY com.id, com.conc, com.volume
) as t2
on t1.id = t2.id and
t1.conc = t2.conc and
t1.volume = t2.volume and
abs((t1.price / my_currency.ex_rate) - t2.usd_price) < 0.01 and
t1.date_g = t2.date_g
ORDER BY conc DESC, volume DESC;
However, if you change the join condition on price to:
t1.price / my_currency.ex_rate = t2.usd_price and
Then it doesn't work.
It does work if you cast both results back to decimal(10, 2):
cast(t1.price / my_currency.ex_rate as decimal(10, 2)) = cast(t2.usd_price as decimal(10, 2))
It might have something to do with this note in the documentation:
In division performed with /, the scale of the result when using two
exact-value operands is the scale of the first operand plus the value
of the div_precision_increment system variable (which is 4 by
default). For example, the result of the expression 5.05 / 0.014 has a
scale of six decimal places (360.714286)
I want to add a survey to a website. And a good survey needs a reporting. Some basic reports are done. Now I want to put some cream on the coffee ...
The table with sample data:
mysql> select * from u001;
+----+----------+------------+-------+---------------------+
| id | drink | sex | age | date |
+----+----------+------------+-------+---------------------+
| 1 | Beer | m | 30-39 | 2012-10-17 23:17:52 |
| 2 | Milk | f | 10-19 | 2012-10-18 00:15:59 |
| 3 | Milk | f | 20-29 | 2012-10-18 23:33:07 |
| 4 | Tea | m | 30-39 | 2012-10-20 22:47:08 |
| 5 | Water | f | 20-29 | 2012-10-20 22:47:30 |
| 6 | Milk | m | 30-39 | 2012-10-20 22:51:22 |
+----+----------+------------+-------+---------------------+
6 rows in set (0.00 sec)
I want to get a result that counts how many women/men likes Tea/Beer/etc.
A desired result like this:
+-------+-----+---------+
| drink | sex | counted |
+-------+-----+---------+
| Beer | m | 1 |
| Milk | f | 2 |
| Tea | m | 1 |
| Water | f | 1 |
| Milk | m | 1 |
+-------+-----+---------+
Have anyone some suggestions or solutions?
Thanks in advance.
SELECT drink, sex, COUNT(id) counted
FROM u001
GROUP BY drink, sex
SQLFiddle Demo
select drink, sex, count(id) from u001 group by drink, sex