mysql query with group by and order - mysql

Table structure:
country
season
points
Current query:
SELECT SUM(points) AS total, country
FROM table
WHERE season >= X
GROUP BY country
ORDER BY total desc
This gives me a nice list ordered by a total points collected by a given country. BUT, if a country is tied with another country, I want to sort by their points in the latest season given, is that possible within the same query? And if so, how? (Remember its grouped at the moment)
example of rows
denmark (country), 1 (season), 10 (points)
denmark (country), 2 (season), 5 (points)
sweden(country), 1 (season), 5 (points)
sweden (country), 2 (season), 10 (points)

Maybe this'll do your trick:
SELECT SUM(points) AS total, country
FROM table
WHERE season >= X
GROUP BY country
ORDER BY total DESC, (SELECT t2.points FROM table t2 WHERE table.country=t2.country ORDER BY t2.season LIMIT 1) DESC

SELECT grp.total, grp.country
FROM
( SELECT SUM(points) AS total, country, MAX(season) AS max_season
FROM table
WHERE season >= X
GROUP BY country
) AS grp
LEFT JOIN
table AS t
ON t.country = grp.country
AND t.season = LATEST_SEASON
ORDER BY
grp.total DESC
, t.points DESC ;

Related

Get distinct values from groups in MySQL

I want to get the id of the lowest points from each team (the team field).
My query works but i need to make sure the following query is good enough with a large table.
I need Simplification and Optimization.
Query:
SELECT T.id from teams as T
INNER JOIN (
SELECT MIN(T1.points) AS P FROM teams AS T1
GROUP BY T1.team LIMIT 5
) TJOIN ON T.points IN (TJOIN.P)
GROUP BY T.team
ORDER BY T.points ASC LIMIT 5
Table teams
id
team (foreign_key)
points (indexed)
1
a
100
2
a
101
3
b
106
4
c
105
5
c
102
Result
id
1
5
3
I believe the query you are looking for is:
SELECT MIN(T.id)
FROM teams as T
INNER JOIN (
SELECT team, MIN(points) AS min_points
FROM teams
GROUP BY team LIMIT 5
) TJOIN
ON T.team = TJOIN.team
AND T.points = TJOIN.min_points
GROUP BY T.team
ORDER BY T.points ASC
LIMIT 5
You need to join based on both the column being grouped by and the min value. Consider the result of your query if multiple teams had a score of 100.
Another way of doing this is to use ROW_NUMBER():
SELECT id
FROM (
SELECT id, points, ROW_NUMBER() OVER (PARTITION BY team ORDER BY points ASC, id ASC) rn
FROM teams
) t
WHERE rn = 1
ORDER BY points ASC
LIMIT 5

MYSQL return all fields based on multiple conditions AND distinct on single column but

I have a event_table as below.
city country event date
london UK Soccer 8/20/2010
toronto CA Basketball 8/12/2011
newyork US Basketball 8/21/2012
LA US Basketball 8/30/2013
.....
I need to get all fields with these conditions:
30 entries only
event = "Baseketball"
order by date
Distinct Country "US".
I tried below:
select distinct on country *
from event_table
where event="Basketball"
order by date Dec limit 20;
and below:
select *
from event_table
where event="Basketball"
order by date Dec limit 20
group by country;
But none working. Thanks for the help in advance.
Fro only one country it is enough to make
SELECT *
FROM event_table
WHERE event="Basketball"
AND country = 'US'
ORDER BY `date` DESC
LIMIT 30
If you want more counties use
SELECT
city, country, event, `date`
FROM
(SELECT *
,ROW_NUMBER() OVER(PARTITION BY county ORDER BY `date` DESC) rn
FROM event_table
WHERE event="Basketball") t1
WHERE rn <= 30
You can then select the countrie you like

How to merge the tailing fields in a sorted result in SQL?

If the following command is executed, we could see that there are 6 results.
> select competition.region, count(competition.score) as cnt from competition group by competition.region order by cnt desc;
## --Result--
CN 80
USA 60
SE 40
US 10
JP 10
KR 8
But what I want is to merge the fields from 4th line to the end into a field called 'other':
## --Result--
CN 80
USA 60
SE 40
OTHER 28
Is there any way to achieve that in a single SQL? Thanks!
Use a derived table to merge the others together:
select region, count(*) as cnt
(select case when competition.region in ('CN', 'USA', 'SE') then competition.region
else 'OTHER'
end as region
from competition) as dt
group by region
order by cnt desc
Edit:
Return 3 most common regions separately. The rest of them as OTHER.
select region, count(*) as cnt
(
select case when region in (select region from competition
group by region
order by count(*) desc
limit 3) then region
else 'OTHER'
end as region
) as dt
group by region
order by cnt desc
Note that only one region will be returned if it's a 3:rd place tie.

mysql order by with limit

I have a query where I want to get the 20 most popular locations from a table, and then order them alphabetically. I'm wondering if there's a cleaner or more efficient way to do this?
SELECT
city
FROM (
SELECT
city,
count(*) AS cnt
FROM locations
GROUP BY city
ORDER BY cnt DESC
LIMIT 20
) s ORDER BY city;
Slightly cleaner:
SELECT city FROM (
SELECT city FROM locations
GROUP BY city
ORDER BY count(*) DESC
LIMIT 20
) s ORDER BY city
You don't need to retrieve the count(*) if you're not going to use it.

Choose company with most records mysql

I have a mysql database with records from different companies. I need to select records from companies which have the most, second most and third most records and plot their number of records per year. How do I select them?
Many thanks.
EDIT:
The table would look something like this:
Company Year
A 1999
A 1999
B 1999
C 1999
A 2000
C 2000
A 2003
So if I select the company with the most records, A has the most records, and the output is;
Year Total
1999 2
2000 1
2003 1
And for the company with second most records, the output is ( in this case, company C)
Year Total
1999 1
2000 1
Third most will be company B.
I'd say something like
SELECT company,COUNT(company) AS rec,year
FROM your_table GROUP BY company, year ORDER BY rec DESC LIMIT 3;
most_frequent:
SELECT year, COUNT(year) AS total FROM your_table
WHERE company =
(SELECT company, COUNT(company) AS c
FROM your_table
GROUP BY c
ORDER BY c DESC
LIMIT 0,1)
second most:
SELECT year, COUNT(year) AS total FROM your_table
WHERE company =
(SELECT company, COUNT(company) AS c
FROM your_table
GROUP BY c
ORDER BY c DESC
LIMIT 1,1)
third most:
SELECT year, COUNT(year) AS total FROM your_table
WHERE company =
(SELECT company, COUNT(company) AS c
FROM your_table
GROUP BY c
ORDER BY c DESC
LIMIT 2,1)
In order to get two dimensional output in one query:
SELECT company, year, COUNT(year) AS total FROM your_table
INNER JOIN
(SELECT company, COUNT(company) AS c
FROM your_table
GROUP BY c
ORDER BY c DESC) AS t1
ON your_table.company = t1.company
ORDER BY t1.c DESC
I'm sorry, I haven't tested it. Just leave a comment if you have any trouble.