How to select province and average weight of people in those provinces only for provinces which average weight of people < 70 - sql

A table named "people" contains the following fields:
first_name
weight
gender
province
A
85
Male
Lubusz
B
95
Female
Lubusz
C
90
Female
Silesia
D
95
Male
Silesia
E
40
Male
Opole
F
50
Female
Opole
How to select the name of province and average weight of people in those provinces, only for provinces which the average weight of people is < 70.
Expected output:
province
Avg_Weight
Opole
45
I have tried the following code:
SELECT province, AVG(weight) AS "Avg_Weight"
FROM people
WHERE "Avg_Weight" < 70 GROUP BY province;
However, the result returns the overall average weight of people in every province.

You need to use HAVING clause & not WHERE clause as fiter is to be done on aggregated column.
select
"province",
avg("weight") as avg_weight
from
people
group by
"province"
having
avg("weight") < 70;
Demo

Related

Oracle Sql Developer (Select Count) Twoc olumns

I have to make a query that has the Total number of customers by country and city
country and city are columns that are inside the customer table
On my own I have managed to get the total number of customers per city like this:
SELECT city, COUNT (*)
FROM employees
GROUP BY city
ORDER BY city
But how do I get it together with the country?
looking for information I think it should be something like this and ordered from largest to smallest
Country
City
TOTAL_CUSTOMERS
USA
Kirkland
3
USA
London
2
UK
Redmond
2
UK
Seattle
1
UK
Tacoma
1
What we have been told is to say Total number of customers by country and city.
You simply add country to the column list and group by list:
SELECT country,city, COUNT(*)
FROM employees
GROUP BY country,city
ORDER BY COUNT(*) DESC

Calculate percentage of students SQL

How to calculate percentage of students with higher mark than average for each course?
Assume I have a table (avg_marks) with average marks for each course and number of students in the course:
course_id avg_mark num_students
12345 74 20
12346 70 17
12347 64 33
...
I also have a table (enrolments) with all courses, students enrolled in those courses and their mark for the course:
course_id student mark
12345 1010 63
12345 2111 75
12345 3221 85
12345 6788 40
...
12347 8989 90
...
The expected output would be the table with course id and percentage of students with higher marks than average:
course_id percentage
12345 40
12345 20
12346 50
...
I have calculated number of students who have higher mark than average, but somehow I wasn't able to calculate the percentage (perhaps because the table contains all courses?). How can I modify this query or make a new one to calculate the percentage of students with higher mark than average?
Number of students with higher than average mark:
SELECT e.course_id, COUNT(e.student)
FROM enrolments e, avg_mark av
WHERE e.mark > av.avg_mark AND e.course_id=av.course_id
Output of the above query was like the following:
course_id count
12345 5
12346 10
12347 8
...
You don't need the table avg_marks.
Use window function AVG() in enrolments to get the average mark for each course_id and then use conditional aggregation with AVG() aggregate function to get the percentage:
SELECT course_id,
ROUND(100 * AVG((mark > avg_mark)::int)) percentage
FROM (SELECT *, AVG(mark) OVER (PARTITION BY course_id) avg_mark FROM enrolments) e
GROUP BY course_id
See the demo.
select
e.course_id,
count(case when e.mark > av.avg_mark then e.student end)/count(*) * 100 as students_cnt_with_mark_above_avg_pct
from enrolments e, avg_mark av
where e.course_id = av.course_id
group by e.course_id

SQL Server How to get number of unique values in a column and average score per values?

I have a table like this
city metric_name metric_value id
Berlin likes 1 1a
Berlin dislikes 2 1a
Berlin comments 3 1a
Berlin likes 4 1b
Berlin dislikes 5 1b
Berlin comments 3 1b
Hamburg likes 1 1c
Hamburg dislikes 2 1c
Hamburg comments 3 1c
Hamburg likes 2 1d
Hamburg dislikes 4 1d
Hamburg comments 5 1d
and so on
My ideal result is this
city city_count_unique average_metric_score
Berlin 2 3 (sum metric_value / sum metric_names)
Hamburg 2 2,8
What I ve done
I got distinct count for every city and avg metric value
SELECT AVG(T.metric_value), T.city,
COUNT(*) AS 'city_count_unique'
FROM
(SELECT DISTINCT metric_value, city
FROM dbo.Table) as T
GROUP BY T.city
But it is false
Appreciate any help
updated
There is also an additional column id in varchar format
The answer here depends on this assumption:
You always have exactly 3 metrics per 'group' (i.e. likes, dislikes
and comments)
If that assumption is correct, the following will output what you are looking for:
SELECT city,
COUNT(metric_name) / 3 AS city_count_unique,
CAST(SUM(metric_value) AS FLOAT) / COUNT(metric_value) AS average_metric_score
FROM #Table
GROUP BY city
Output:
city city_count_unique average_metric_score
Berlin 2 3
Hamburg 2 2.83333333333333
How does this work?
By grouping on the city, we combine results for each city individually.
The count of metric_name gives the total metrics for that city (which is 6 in the case of your example). I divide this by 3 to give the unique count (based on the assumption I stated).
The average_metric_score calculation if the total of the metric_value for each city divided by the number of metrics (so 18 / 6 for Berlin). The reason for the CAST to FLOAT is to allow for a floating point answer. You could also use CONVERT if you prefer this to CAST.
Edit following OP update to question
OP edited the question to indicate that there is an ID column that allows the detection of metric grouping. This is an update to use that rather than assuming there are always 3 metrics per group.
SELECT city,
COUNT(id) AS city_count_unique,
CAST(SUM(metric_value_total) AS FLOAT) / SUM(metric_value_count) AS average_metric_score
FROM (
SELECT city,
id,
SUM(metric_value) metric_value_total,
COUNT(metric_value) AS metric_value_count
FROM #Table
GROUP BY city, id
) a
GROUP BY city
You seem to want:
SELECT city,
COUNT(DISTINCT id) as city_count_unique,
AVG(metric_value * 1.0) as average_metric_score
FROM t
GROUP BY city;

How to select students who got above average?

How to list all students who got above average grade of their group in SQL table? We have 6 group_ids so there six different average grades.
group_id student grade
1 James 85
1 Adam 96
2 Tom 56
2 Jane 89
2 Anny 90
Result:
group_id student grade
1 Adam 96
2 Jane 89
2 Anny 90
ashkufaraz's answer is closer but not quite right
select group_id,student,grade from students one where grade >
(select avg(grade) from students two where two.group_id = one.group_id)
The question is just tagged SQL, so this is an answer using standard SQL:
One option is to use a window function:
select group_id,student,grade
from (
select group_id,student,grade,
avg(grade) over (partition by group_id) as group_avg
from studends
) t
where grade > group_avg;
This has the additional benefit that you can also display the group average along with the result with no additional join or sub-select.

count multiple values from single column

I have a table with customer information like date of birth, address, contactinfo, etc.
I want to count the number of customers per city with a single query that outputs two values per record, cityname and amount of customers living there:
Alabama 285
Kentucky 167
New York 4
Rio de Janeiro 950
etc...
There are hundreds of cities in the table so I can't do a
SELECT count(CASE WHEN city = 'Alabama' THEN 1 END) AS Alabama
You can use GROUP BY clause to count the number of customers per city :
SELECT city
, COUNT(*)
FROM table
GROUP BY city