Count exclude max an min occurances - mysql

For eg. if we go to w3schools:
And put
SELECT City, count(City) as Occurrences
FROM Customers
GROUP by City
ORDER BY count(City) DESC
But what I really want is to exclude max and min occurances (ignore hard-coded 6 and 1 values for max and min), like
SELECT City, count(City) as Occurances
FROM Customers
GROUP by City
HAVING count(City) != 6 AND count(City) != 1
ORDER BY count(City) DESC
What would be the way to get desired output without hard-coding 6 and 1?

you can try with this
select c1.city, c1.cnt from (
select city, count(*) cnt from customers c
group by city
) c1 inner join
(select max(cnt) max_cnt, min(cnt) min_Cnt from (
select city, count(*) cnt from customers c
group by city
)) c2
on c1.cnt!=c2.max_cnt and c1.cnt!=c2.min_cnt
;
as MySQL doesn't have an OVER..PARTITION BY function, which could maybe be useful.
Another approach could be on rownums and ordering but I prefer this

Try this
SELECT City, count(City) as Occurences FROM Customers,
(SELECT MAX(Occur) AS Ma,MIN(Occur) AS Mi FROM (SELECT City, count(City) as Occur
FROM Customers GROUP by City)) as T
GROUP BY City HAVING Occurences!=T.Ma AND Occurences!=T.Mi ORDER BY Occurences DESC

Related

How do I return only one row with MAX() aggregate?

SELECT Name, MAX(Population) as Population
FROM County
GROUP BY Name;
Question: This just returned 16 rows... I want to return only the ONE county which has the highest population, showing 1 row with with the name of that county and its population,, not the highest population for every county. How do I fix this?
Thanks in advance.
Order and take first
SELECT Name,
Population
FROM County
ORDER BY Population DESC LIMIT 1
with data (Population, Name) as(
Select '12345' ,'c1' union all
Select '1234500001' ,'c2' union all
Select '1234500002' ,'c3' union all
Select '12346' ,'c4' union all
Select '1234600001' ,'c4' union all
Select '1234600002' ,'c4' )
SELECT Name, Population
FROM data
where Population = (SELECT MAX(Population) FROM data)
;

SQL Aggregate Fraction

I have a table with City and ComplaintType.
I am trying to create a normalization column that has the following computation:
(pseudo) select number of a particular type in a particular city) / (number of all complaints in a particular city
I currently have the following SQL:
SELECT City AS city_name, ComplaintType AS complaint_type,
count(*) / (SELECT count(City) FROM data GROUP BY City) AS complaint_frac,
count(*) AS count_freq,
(SELECT count(City) FROM data GROUP BY City) AS count_city
FROM data
GROUP BY City, ComplaintType
ORDER BY complaint_frac DESC
Which gives me the following table:
The total complaints in a city (count_city) is incorrect. However, when I run the count_city query on it's own, the counts are correct and give the following output:
How do I correctly get my city_count associated with the number of x complaints by city so I can compute the correct fraction?
Cold hard numbers example:
Bronx & Hot Water = 79690
Bronx (total complaints) = 579363
complaint_frac = 79690 / 579363 = 0.13754761695
correlate your subquery in your main table.
SELECT City AS city_name, ComplaintType AS complaint_type,
count(*) / (SELECT count(City) FROM data GROUP BY City) AS complaint_frac,
count(*) AS count_freq,
(SELECT count(d1.City) FROM data d1 WHERE d1.City = d2.City GROUP BY d1.City) AS count_city
FROM data d2
GROUP BY City, ComplaintType
ORDER BY complaint_frac DESC
You don't need subqueries for this, at least in MySQL 8+; window functions do the work:
SELECT City AS city_name, ComplaintType AS complaint_type,
count(*) / sum(count(*)) over (partition by city) as complaint_frac,
count(*) as count_freq,
sum(count(*)) over (partition by city) as count_city
FROM data
GROUP BY City, ComplaintType
ORDER BY complaint_frac DESC

My sql get id which has maximum likes grouped by column and ordered by sum(likes)

I need to retrieve data from a view. View will have details such as country, location_id, content_id, content_url, content_likes and .... I need to retrieve location_id which has max(content_likes) grouped by country order by sum(content_likes) desc.
Right now I am getting the correct data based on country side, but Id I am getting which is of default order. But instead of default ordered id I need to get Id which has maximum likes.
My current query is
select * from <view_name> group by country order by sum(content_likes) desc;
Data From View:
Result :
You seem to want something like:
select country_id, location_id, sum(content_likes)
from view_name vn
group by country_id, location_id
having location_id = (select vn2.location_id
from view_name vn
where vn2.country_id = vn.country_id
group by location_id
order by sum(content_likes) desc
limit 1
);
You can try this (sorry any syntax error):
select cc.*
from
(select aa.location_id, aa.country /*[, add fields if you need them...]*/,
rank() over (partition by aa.country_id order by aa.content_likes) ranking_field
from <view_name> aa
join (select country, sum(content_likes) sum_content_likes
from <view_name>
group by country) bb
on aa.country=bb.country) cc
where ranking_field=1
order by cc.sum_content_likes desc
This returns only the location with max likes in each country ordered by the total likes in each country
EDIT:
With your new example, perhaps you can do simply this:
SELECT *
FROM <<view>> aa
JOIN(SELECT country, MAX(content_likes) max_likes
FROM <<view>>
GROUP BY country) bb
ON aa.country=bb.country
AND aa.content_likes=bb.max_likes
It is two pass query but give your example result. It can return more than one row for country if more than one location has same likes number and those are the max likes in that country.
Hope this help you.
My issue resolved with below sql
select t.location_id,t.content_likes from
(select country,max(content_likes) as mcl,sum(content_likes) as scl from test_eresh
group by country) x,
test_eresh t
where t.country = x.country
and t.content_likes = x.mcl
order by x.scl desc

Using Subquery in having clause using alias

I have a Mysql Query where
Where i have a table as like below(Sample data)
Employee_id Months Salary
1 10 200
2 20 300
3 30 400
Now i wanted to find the Number of Employees who are having the Maximum total salary
(Total salary =month * salary)
So i have my query like this
Subquery:
((select max(mon_sal.mc) as max_mc from (
select months*salary as mc from employee group by employee_id) as mon_sal)
as max_mon_sal)
//To find the Maximum of Total salary
Now my problem is i need to find the number of persons having the maximum salary,
select max_mon_sal.max_mc,name
from employee group by employee_id
having salary=max_mon_sal.max_mc from (
(select max(mon_sal.mc) as max_mc from
(select months*salary as mc from employee group by employee_id) as mon_sal)
as max_mon_sal)
Its showing Error.I have problem with using the max_mon_sal alias.Please suggest.
You can simply use:
select count(*)
from employee
where months * salary = (
select max(months * salary)
from employee
);
SELECT COUNT(*) no_of_employees
FROM my_table a
JOIN
( SELECT MAX(months*salary) total FROM my_table ) b
ON b.total = a.months * a.salary;
I don't no sure if this is what are looking for, even the better solution for this case is to use temporary tables:
SELECT Employee.employee_id,SUM(MONTHs * salary)
FROM Employee,
(
SELECT MAX(total) value FROM (
SELECT SUM(MONTHs * salary) as total
FROM Employee
GROUP BY employee_id
) T
) D
GROUP BY Employee.employee_id,D.value
HAVING SUM(MONTHs * salary) = D.value

MySQL: calculate percent in subgroup

I have a list of names with country and city.
| COUNTRY | CITY | NAME | ID|
I need to find a count of each name grouped by country and city. I also need percentage of each name WITHIN each city/country. For example:
RESULTS
SELECT count(ID), country, city, name
from table NAME
GROUP BY country, city, name
How do I calculate percentage of each name WITHIN each city/country?
It looks like your query doesn't compute the count of each name grouped by city and state but rather the count of each id grouped by name, city and country. Assuming this is what you wanted, then the percents might be calculated like this:
SELECT count(N.ID) as NameCount
, count(N.ID) * 100.0 / (SELECT COUNT(*) FROM NAME WHERE Country = N.Country AND City = N.City) as NamePercent
, N.Name
, N.Country
, N.City
FROM NAME N
GROUP BY N.country, N.city, N.Name
Here's a test fiddle I've created for it: http://sqlfiddle.com/#!2/875026/1/0
For the second question - from the comments,
How to calculate AVE of name occurance across different cities grouped by a country. For example: count of Mikes in NY-2, Chicago-4, LA-5. So ave for Mike in US is 3.6
You might do something like this:
SELECT Name
, Country
, AVG(NameCount) NameAvgAcrossCountry
FROM
(SELECT count(N.ID) as NameCount
, count(N.ID) * 100.0 / (SELECT COUNT(*) FROM NAME WHERE Country = N.Country AND City = N.City) as NamePercent
, N.Name
, N.Country
, N.City
FROM NAME N
GROUP BY N.country, N.city, N.Name) NamesQuery
GROUP BY Name, Country