Query set restriction SQL database - sql

Name Gender School Position Salary
-----------------------------------------------------------
Alex Male Computing Lecturer $80,000
Bob Male Mathematics Lecturer $60,000
Carol Female Mathematics Lecturer $100,000
Diana Female Computing Lecturer $60,000
Ewen Male Physics Lecturer $72,000
Fran Female Physics Lecturer $88,000
Gary Male Computing Administrator $40,000
Humphry Male Mathematics Lecturer $72,000
Ivana Female Computing Tutor $12,000
Je Male Physics Administrator $80,000
Kim Female Mathematics Lecturer $100,000
Lex Male Computing Tutor $12,000
Morris Male Engineering Tutor $15,000
Assume you only have a statistical interface, so only aggregate queries will be successful. You know Diana is a female Computing Lecturer. The questions below explore how we might determine her salary using inference, in the presence of various query size restrictions.
Suppose that there is a lower and upper query size limit that satisfies
k jX(C)j N 􀀀 k
with k = 2. Show a sequence of queries that could be used to determine Diana's salary.
This is a school question can anyone help me out?

One agregated function, with conditional SUM()
SELECT SUM(CASE WHEN Name = 'Diana' THEN Salary ELSE 0 END) as salary
FROM YourTable
Now dont know what was all that lower upper query size.
or
SELECT Max(Salary)
FROM YourTable
WHERE School = 'computing'
AND Gender = 'Female'
AND Position = 'Lecturer'

Related

Change column values to column headers in Postgres SQL replacing with values from another column

I am unable to figure out how to make a column values into column headers and assign appropriate values as it happens
Say I have a Postgres database with the following table:
Name Subject Score Region
======= ========= ======= =======
Joe Chemistry 20 America
Robert Math 30 Europe
Jason Physics 50 Europe
Joe Math 70 America
Robert Physics 80 Europe
Jason Math 40 Europe
Jason Chemistry 60 Europe
I want to select/fetch data in the following form:
Name Chemistry Math Physics Region
======= ========== ======= ======== ========
Joe 20 70 null America
Robert null 30 80 Europe
Jason 60 40 50 Europe
Considering that there are 80 subjects. How do I write an SQL select statement that returns data in this format?
In Postgres, I recommend using the FILTER syntax for conditional aggregation:
SELECT name,
MAX(score) FILTER (WHERE subject = 'Chemistry') AS Chemistry,
MAX(score) FILTER (WHERE subject = 'Math') AS Math,
MAX(score) FILTER (WHERE subject = 'Physics') AS Physics
FROM grades
GROUP BY name

Loop through a table based on multiple conditions

Students table
student_id student_name
1 John
2 Mary
Grades table
student_id year grade_level school Course Mark
1 2015 10 Smith High Algebra 95
1 2015 10 Smith High English 96
1 2016 11 Smith High Geometry 85
1 2016 11 Smith High Science 88
2 2015 10 Smith High Algebra 98
2 2015 10 Smith High English 93
2 2016 11 Smith High Geometry 97
2 2016 11 Smith High Science 86
I'm trying to show results for each year and what class a student took with the grade.
So the final output i'm looking for is something like:
[student_id1] [year1] [grade1] [school1]
[course1] [mark1]
[course2] [mark2]
[course3] [mark3]...
[student_id1] [year2] [grade2] [school1]
[course1] [mark1]
[course2] [mark2]
[course3] [mark3]...
[student_id2] [year1] [grade1] [school1]
[course1] [mark1]
[course2] [mark2]
[course3] [mark3]...
This would all go in one column/row. So in this particular example, this would be my result:
1 2015 10 Smith High
Algebra 95
English 96
1 2016 11 Smith High
Geometry 85
Science 88
2 2015 10 Smith High
Algebra 98
English 93
2 2016 11 Smith High
Geometry 97
Science 86
So anytime a student id, year, grade, or school name changes, I would have a line for that and loop through the classes taken within that group. And all of this would be in one column/row.
This is what I have so far but I'm not sure how I can properly loop through course and grades for each group. I'd appreciate it if I can be pointed in the right direction.
select s.student_id + '' + year + '' + grade_level + '' + school
from students
join grades on students.student_id = grades.student_id
If you want to do it in your SQL Enviromnment, it depends on the Database Management System you are using.
For example, if you are using Transact SQL you can try to look at this link.
Generally this kind of loops and interactions are done in the programming language that is coupled with the SQL DB.
Anyway, you should look at Stored Procedures and Cursors if you really want to do this in SQL.
You are trying to mix presentation with retrieval of data from database tables. Looping through the resultset in sql can be achieved via cursor but that isn't adviced. You are better off by pulling the required data using two queries and later print it using a language of your choice.

Obtain percentage of values in a column

I have a table called Director, which looks like
DirectorID FirstName FamilyName FullName DoB Gender
1 Steven Spielberg Steven Spielberg 1946-12-18 Male
2 Joel Coen Joel Coen 1954-11-29 Male
3 Ethan Coen Ethan Coen 1957-09-21 Male
4 George Lucas George Lucas 1944-05-14 Male
5 Ang Lee Ang Lee 1954-10-23 Male
6 Martin Scorsese Martin Scorsese 1942-11-17 Male
7 Mimi Leder Mimi Leder 1952-01-26 Female
I am trying to work out the percentage of Female to Male directors
I can work out the number of Male and Female Directors using:
SELECT count(*) as myMale from Director
where Gender = 'Male'
SELECT count(*) as myFemale from Director
where Gender = 'Female')
But I am having trouble combining them to obtain a percentage of Female Directors.
I am looking for the result of 14.3%, which is calculated using:
Total Female Directors / (Total Male Directors + Total Female Directors)
or
1/(6+1)
How would I do this with SQL?
A simple method uses aggregation. Assuming directors are either male or female (binary), then a simple conditional aggregation suffices:
select avg(case when gender = 'Female' then 1.0 else 0 end) as ratio_female
from directors;
If you want to limit this only to male and female (assuming other options), then include where gender in ('female', 'male').

Select distinct count over two columns

I have data that looks like this:
school district crs_sbj crs_num crs_sec
CANYON HIGH IRON DISTRICT ENGL 2010 213
CANYON HIGH IRON DISTRICT ENGL 2010 214
CANYON HIGH IRON DISTRICT ENGL 1010 110
CANYON HIGH IRON DISTRICT MATH 1010 400
WAYNE HIGH WAYNE DISTRICT MATH 1010 321
WAYNE HIGH WAYNE DISTRICT MATH 1010 322
WAYNE HIGH WAYNE DISTRICT ENGL 1010 500
I want to count the unique classes offered at each individual high school.
For example, I want to see:
count school
3 CANYON HIGH
2 WAYNE HIGH
How would I go about doing this? I understand the concept of one column, but how about two?
Try this:
select school, count(distinct crs_num) _count
from table
group by school;
Select School, count(distinct crs_num)
from table
group by School
I am unsure what constitutes a unique class.
; with aardvark (select distinct school, district, crs_sbj, crs_num
from T)
select district, school, count(*)
from aardvark
group by school, district
Since the same school name can be used across districts, I included the district in the grouping.

List the Id who appeared once only in Relational Algebra

Let's say there's a table called Winner, with 3 attributes: Name, Gender and Id.
Name Gender Id
Kevin Male 8
Kevin Male 8
Benny Male 31
Jenny Female 7
Louie Male 4
Peter Male 11
Kevin Male 2
Jenny Female 7
Jenny Female 7
Chris Male 23
Louie Female 14
Apart from those people who is actually 2 different person but with the same name and those people who have the same name but with different gender, their Id's will be the unique value to identify themselves. If I want to list all the Id's who appeared once only in the list, I am thinking to do something like this:
Am I expressing it correctly ?
I don't know what your formula is trying to say, but in SQL you can achieve the result you want with a GROUP BY query:
SELECT Id, COUNT(Id) AS idCount
FROM Winner
GROUP BY Id
HAVING COUNT(Id) = 1