I have a table like this:
LocationID CountryName CustomerAmount
C01 Australia 500
C02 Australia 200
C03 China 100
C04 China 200
C05 Japan 50
C06 Canada 120
I want to find the "number of customers in each country" AND the total number of customers.
Now I have the following query:
select countryName, sum(CustomerAmount)
from test
group by countryName;
I obviously got this output:
CountryName. customerAmount
Australia 700
China 300
Japan 50
Canada 120
But I want the output like this
CountryName. customerAmount totalAmount
Australia 700 1170
China 300 1170
Japan 50 1170
Canada 120 1170
My problem is how can I put two same sum(customerAmount) side by side, but one is grouped by countryName, while the other just sum up all values in customerAmount table.
Thank you in advance!!!! I have to say sorry as my expression may be ambiguous.
One easy way is just to use a sub-query like
select countryName, sum(CustomerAmount) customerAmount,
(select Sum(customerAmount) from test) totalAmount
from test
group by countryName;
If you can use window functions (MySql 8+) you can do
select countryName, sum(CustomerAmount) customerAmount,
sum(Sum(CustomerAmount)) over() totalAmount
from test
group by countryName;
note the nested sum().
SELECT countryName, SUM(CustomerAmount), SUM(CustomerAmount) OVER()
FROM test
GROUP BY countryName;
I did not test this, but using the over clause should do what you are looking for as seen here.
Related
I have a query that can return the intended value but only 1 row. I need to have at least 26 rows of the values due based on the having clause.
Town
floor_area_sqm
resale_value
toronto
30
4500
chicago
44
300
toronto
22
3000
sydney
54
3098
pittsburg
102
2000
sydney
101
2000
pittsburg
129
2000
SELECT town, floor_area_sqm, resale_price
FROM X.flat_prices as X
GROUP BY town
HAVING Min(floor_area_sqm) = (SELECT MIN(floor_area_sqm) FROM X.flat_prices HAVING MAX(resale_price));
By using the formula above I get this:
Town
floor_area_sqm
resale_value
chicago
44
300
So the answer should show something like the following:
Town
floor_area_sqm
resale_value
chicago
44
300
toronto
22
3000
sydney
54
3098
pittsburg
102
2000
It should pull the lowest sqm for the town with the highest resale value. I got 26 towns and a database of over 200k.
I would like to replicate with MAX sqm using the same formula. Is join the way/only way to do it?
Use a subquery to get the minimum sqm for each town. Join that with the table to get all the properties with that sqm. Then get the maximum resale value within each of these groups.
SELECT t1.town, t1.floor_area_sqm, MAX(t1.resale_value) AS resale_value
FROM flat_prices AS t1
JOIN (
SELECT town, MIN(floor_area_sqm) AS floor_area_sqm
FROM flat_prices
GROUP BY town
) AS t2 ON t1.town = t2.town AND t1.floor_area_sqm = t2.floor_area_sqm
GROUP BY t1.town, t1.floor_area_sqm
DEMO
In MySQL 8.0 you can do it in one query with window functions, but I still haven't learned to use them.
This one goes for the highest resale price , then choose the one with the lowest sqm if multiple choices exist.
select t1.town ,min(floor_area_sqm) mi_sqm,resale_value from flat_prices t1
join
(select town,max(resale_value) mx_value from flat_prices group by town) t2
on t1.town=t2.town and resale_value=mx_value
group by town
;
I have recently attended an interview on SQL. Below is the question:
Write a query to retrieve city name, state name, city population and return the following calculations along with the before mentioned fields.
Average city population in the state.
Difference between the city population and average city population in that state.
City Table:
City_Name
State_NAme
Population
Baltimore
Maryland
30000
College Park
Maryland
18000
Columbia
Maryland
20000
Boston
Massachusetts
35000
Malden
Massachusetts
10000
Dover
Delaware
20000
Jersey City
New Jersey
35000
I have tried below query but I didnot get desired output. Can anyone help me with correct query?
select * from city_table;
select state_name, sum(population)/count(city_name) as average_city_pop
from city_table
group by state_name;
You need to explore sql more, learn about aggregation functions and joins. Your query is correct in obtaining the average population. You need to join it to the original table to get your result.
with avg_city_pop as (select state_name, avg(population) as avg from city group by state_name)
select c.*, acp.avg as average_city_population, abs(acp.avg-c.population) as difference from city c inner join avg_city_pop acp on c.state_name = acp.state_name;
try it out here
For MySQL versions before 8.0, we can use a correlated subquery to get the average population for each state, which can alss be used to calculate the gap between city population and state average population. Note, the abs function is optionally used to always return a positive number. Omit it if necessary.
select city_name,state_name,(select avg(population) from city where state_name=c.state_name group by state_name ) as average_pop ,
abs(population - (select avg(population) from city where state_name=c.state_name group by state_name )) as gap_pop
from city c;
select
city_name,
state_name,
population,
avg(population) over (partition by state_name) as Avg_pop,
population-avg(population) over (partition by state_name) as Difference
from city;
see sqlfilldle: https://www.db-fiddle.com/f/tVxdH6bQvsu48umWgLmrQB/0
This needs MySQL 8.0+, because over_clause is available since 8.0.
output:
city_name
state_name
population
Avg_pop
Difference
dover
delaware
20000
20000.0000
0.0000
baltimore
maryland
30000
22666.6667
7333.3333
college park
maryland
18000
22666.6667
-4666.6667
columbia
maryland
20000
22666.6667
-2666.6667
boston
massachussets
35000
22500.0000
12500.0000
molden
massachussets
10000
22500.0000
-12500.0000
jersey city
new jersey
35000
35000.0000
0.0000
I have a table with 3 columns source, dest, total cost and have values like
Agra Delhi 500
Agra Kanpur 400
Delhi Agra 900
Kanpur Agra 500
I want total cost like
Agra<-->Delhi 1400
Agra<-->Kanpur 900
You can use LEAST() and GREATEST() functions, and a GROUP BY query:
SELECT
LEAST(source, dest),
GREATEST(source, dest),
SUM(total_cost)
FROM
tablename
GROUP BY
LEAST(source, dest),
GREATEST(source, dest)
SELECT a.source, a.dest, (a.total_cost + b.total_cost) round_trip_cost
FROM my_tab as a
LEFT OUTER JOIN my_tab as b
ON (a.source = b.dest AND b.source = a.dest)
I have two tables on MySQL (using phpMyAdmin), looking like the following:
Table 1:
Country Total Minutes
USA 100
USA 90
Canada 60
Mexico 80
UK 90
France 70
France 10
Germany 10
In Table 2, what I need to do is the following:
Region Total Minutes
North America USA+USA+Canada+Mexico Mins
Europe UK+France+France+Germany Mins
Is there a way to have a row be the result of a query?
You either need a region column in table 1:
SELECT region, SUM(`Total Minutes`)
FROM timespent
GROUP BY region;
Or a separate region <-> country table:
SELECT region, SUM(`Total Minutes`)
FROM myregions r
INNER JOIN timespent t USING (country)
GROUP BY r.region;
The regions table would look like this:
region | country
--------------+--------
North America | USA
North America | Mexico
If you can't change anything in your database, look at Andomar's solution :)
You could translate the countries to regions in a subquery. The outer query can then group by on region:
select Region
, sum(TotalMinutes) as TotalMinutes
from (
select case country
when 'USA' then 'North America'
when 'France' then 'Europe'
end as Region
, TotalMinutes
from YourTable
) as SubQueryAlias
group by
Region
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