So, for example i've got the following table;
ID COUNTRY VALUE
--------------------- -------------------- --------------------
1 India 12000
2 India 11000
3 UK 11000
4 India 15000
5 Canada 11000
And I would like to group by Country but only have the country with the highest value show up, if I would just use a group by query like:
SELECT * FROM countries GROUP BY country
I would get;
ID COUNTRY VALUE
--------------------- -------------------- --------------------
1 India 12000
3 UK 11000
5 Canada 11000
Where the value for india would be 12000. I would like the query to group on the highest value for the group by on country like:
ID COUNTRY VALUE
--------------------- -------------------- --------------------
3 UK 11000
4 India 15000
5 Canada 11000
So it's grouped on the highest value which is 15000.
DEMO
SELECT s1.ID, s1.COUNTRY, s1.VALUE
FROM countries s1
LEFT JOIN countries s2
ON s1.VALUE < s2.VALUE
AND s1.COUNTRY = s2.COUNTRY
WHERE s2.COUNTRY IS NULL;
OUTPUT
NOTE: But be carefull of ties. In that case you can get one random from those ties.
You can use the MAX aggregate function.
select
country,
max(value) value
from countries
group by
country
See the live example.
Edit: The original solution was only correct due to the nature of the data. I've removed the ID from the first query, to correct the mistake. Here is another solution (based on #Juan Carlos Oropeza's work - thank you) that will return the ID and eliminate the ties.
select
min(x.id) id,
x.country,
x.value
from (
select
c.*
from countries c
left join countries c1 on c.value < c1.value and c.country = c1.country
where c1.country is null
) x
group by
x.country,
x.value
;
See the live example - I've modified the data to cover edge cases mentioned above.
Related
Suppose I have this table I want to query a person and the result should be to get sum of numbers devided by country's total
Country person number
USA A 3
USA A 2
USA C 2
RUS B 1
RUS C 3
IND A 2
DEU A 1
DEU D 1
Suppose I query person A
I want to get
USA 5/7
IND 2/2
DEU 1/2
SUM OF NUMBER / SUM OF COUNTRY
for person A
Now suppose I want to complicate things even further.. suppose I have a month column I want to get for each month these results
You can use conditional aggregation and /:
select country,
sum(case when person = 'A' then number else 0 end) / sum(number)
from t
group by country;
You can try the below -
DEMO
select country, person, sum(number) sum_of_number,
(select sum(number) from t t1 where t.country=t1.country) sum_of_country
from t
where person='A'
group by country, person
Hi I’ve a table database1
3 columns : customer_id , income , country
Customer_id
1001
1002
...
Income
5000
6000
7000
Country
SG
HK
VN
...
How do I write a query that returns the lowest 100 earning customers per country?
Is it possible to return:
Customer ID | country code
1003 SG
1004 SG
...
1007 VN
...
So on
Thanks!
On mySQL 8 you can leverage a window function for this:
SELECT * FROM
(
SELECT
country,
customer_id,
row_number() over(partition by country order by income asc) earn_rank
FROM table
)x
WHERE x.earn_rank <= 100
You can conceive that this window function will sort the rows by country then by income, then start counting up from 1. Each time the country changes the row numbering starts over from 1 again. This means that for every country there will be a row numbered 1 (with the lowest income), and a 2, 3 etc. If we then wrap it up in another outer query that selects only rows where the number is less than 101 we get 100 rows per country
I essentially like to have one query which I'll execute one time and like to have the result (no multiple query execution) and definitely, the query should use simple MySQL structure (no complex/advanced structure to be used like BEGIN, loop, cursor).
Say I've two tables.
1st Table = Country (id(PK), name);
2nd Table = Businessman (id(PK), name, city, country_id(FK))
Like to SELECT all countries, whose businessmen are from distinct cities. No two businessmen exist in one country, who are from the same city. If so, that country will not be selected by the SELECT clause.
Country
id name
1 India
2 China
3 Bahrain
4 Finland
5 Germany
6 France
Businessman
id name city country_id
1 BM1 Kolkata 1
2 BM2 Delhi 1
3 BM3 Mumbai 1
4 BM4 Beijing 2
5 BM5 Paris 6
6 BM6 Beijing 2
7 BM7 Forssa 4
8 BM8 Anqing 2
9 BM9 Berlin 5
10 BM10 Riffa 3
11 BM11 Nice 6
12 BM12 Helsinki 4
13 BM13 Bremen 5
14 BM14 Wiesbaden 5
15 BM15 Angers 6
16 BM16 Sitra 3
17 BM17 Adliya 3
18 BM18 Caen 6
19 BM19 Jinjiang 2
20 BM20 Tubli 3
21 BM21 Duisburg 5
22 BM22 Helsinki 4
23 BM23 Kaarina 4
24 BM24 Bonn 5
25 BM25 Kemi 4
In this respect, China and Finland shouldn't be listed.
I've attempted using count and group by, but no luck.
Can you please help me to build up this query.
Here it is, all you need is to join Businessman table and count cities and distinct cities and if they equal that means all businessmen are from different cities:
SELECT
c.`id`,
c.`name`,
COUNT(b.`id`) AS BusinessmanCount,
COUNT(b.`city`) AS CityCount,
COUNT(DISTINCT b.`city`) AS DistinctCityCount
FROM `countries` c
INNER JOIN Businessman b ON c.`id` = b.`country_id`
GROUP BY c.`id`
HAVING CityCount = DistinctCityCount
For minified version what you exactly need:
SELECT
c.`id`,
c.`name`
FROM `countries` c
INNER JOIN Businessman b ON c.`id` = b.`country_id`
GROUP BY c.`id`
HAVING COUNT(b.`city`) = COUNT(DISTINCT b.`city`)
Well, I think we should have waited for you to show your own query, because one learns best from mistakes and their explanations. However, now that you've got answers already:
Yes, you need group by and count. I'd group by cities to see if I got duplicates. Then select countries and exclude those that have duplicate cities.
select *
from country
where id not in
(
select country_id
from businessmen
group by city, country_id
having count(*) > 1
);
You need either nested aggregations:
select *
from Country
where id in
(
select country_id
from
(
select city, country_id,
count(*) as cnt -- get the number of rows per country/city
from Businessman
group by city, country_id
) as dt
group by country_id
having max(cnt) = 1 -- return only those countries where all counts are unique
)
Or compare two counts:
select *
from Country
where id in
(
select country_id
from Businessman
group by country_id
having count(*) = count(distinct city) -- number of cities is equal to umber of rows
)
I have a table say City. I have state as a foreign key in it. What query I need to write to get the Top 5 states which occur in the city table.
Eg
Id City State
1 Mumbai Maharashtra
2 Pune Maharashtra
3 Amritsar Punjab
Here the output I expect is to get as names of the states with count
State_Name count
Maharashtra 2
Punjab 1
SELECT p.name, count(pr.State) FROM City pr
join state p on p.Id = pr.StateId;
Use Group by with count aggregate to count the state and use Limit to filter the records
select count(1) Cnt,state
from yourtable
group by state
order by Cnt desc Limit 5
Let's say I have the following table :
Name - Country - Age
--------------------
Toto - Switzerland - 10
Titi - France - 12
Tata - Italy - 21
Tutu - England - 13
Tete - Italy - 14
I want to create a sql query as simple as possible to regroup people living in defined grouped countries like :
Group A = Switzerland + Italy
Group B = France + England
I don't know how to create a group withn my records with a column that could have multiple different values in the same group...
Could somebody help me with this ?
More information : SQL Server 2008 database.
You mean like this?
SELECT COUNT(Name), GroupA, GroupB FROM
(`SELECT Name, Country, Age,
Country='Switzerland' OR Country='Italy' As GroupA,
Country='France' OR Country='England' As GroupB)
Group By GroupA, GroupB
Select * from (select *,case when Country ='Switzerland' then 'A'
when Country ='Italy' then 'A'
when Country ='France' then 'B'
when Country ='England' then 'B'
else 'C' end) classification from table1)
order by classification
This will group the ppl as per your criteria. If this grouping is static you can have seprate table and use inner join. That will make query more readable