Help with SQL query (Calculate a ratio between two entitiess) - sql

I’m going to calculate a ratio between two entities but are having some trouble with the query.
The principal is the same to, say a forum, where you say:
A user gets points for every new thread. Then, calculate the ratio of points for the number of threads.
Example:
User A has 300 points. User A has started 6 thread. The point ratio is: 50:6
My schemas look as following:
student(studentid, name, class, major)
course(courseid, coursename, department)
courseoffering(courseid, semester, year, instructor)
faculty(name, office, salary)
gradereport(studentid, courseid, semester, year, grade)
The relations is a following:
Faculity(name) = courseoffering(instructor)
Student(studentid) = gradereport (studentid)
Courseoffering(courseid) = course(courseid)
Gradereport(courseid) = courseoffering(courseid)
I have this query to select the faculty names there is teaching one or more students:
SELECT COUNT(faculty.name) FROM faculty, courseoffering, gradereport, student WHERE faculty.name = courseoffering.instructor AND courseoffering.courseid = gradereport.courseid AND gradereport.studentid = student.studentid
My problem is to find the ratio between the faculty members salary in regarding to the number of students they are teaching.
Say, a teacher get 10.000 in salary and teaches 5 students, then his ratio should be 1:5.
I hope that someone has an answer to my problem and understand what I'm having trouble with.
Thanks
Mestika
Some further explanation and examples on my problem and request:
Employee 1: Salary = 10.000 | # of courses he teaches: 3 | # of students (totaly) following thoes 3 courses: 15.
Then, Employee 1 earns 666,7 pr. each student. (i believe this is the ratio)
Employee 2: Salary = 30.000 | # of courses he teaches: 1 | # of students (totaly) following thoes 3 courses: 6.
Then, Employee 2 earns 5000 pr. each student.

You are completely right that my own ratio examples don’t make sense so I will try to explain further.
What I am seeking to do is, to find out how much salary each faculty member has depending on the number of students they are teaching. I imagine that it is a simple question about dividing a faculty members salary by the number of students following a course that the member is teaching.
I get an error when I am running your query, my MySQL has a problem with the convert part (it seems) but otherwise you query is correct it seems.
I haven’t tried the convert statement before, but is it (and why) necessary to convert them? If I for each faculty member that has the correct conditions, find the number of students that are attending the course. Then take that faculty members salary and divide it by the found numbers of student?

when I look at your first example it says that 300 points for 6 threads works out to 50:6 rato. Don't you mean in your later example that 10000 salary for 5 students works out to 2000:5 ratio? not 1:5 ratio?
anyway if my understanding of your example is correct then this should be a good solution
select f.name, f.salary, count(s.studentid) as noofstudents, convert(f.salary / count(s.studentid),varchar(50)) + ':' + convert(count(s.studentid),varchar(10)) as ratio
from faculty f
inner join courseoffering co on f.name = co.instructor
inner join gradereport gr on co.courseid = gr.courseid
inner join student s on gr.studentid = s.studentid
where co.semester = #semester
and co.year = #year
group by f.name, f.salary
perhaps you could expand on your question a bit if this isn't what you're looking for.

Related

Having SQL Server choose and show one record over other

Ok, hopefully I can explain this accurately. I work in SQL Server, and I am trying to get one row from a table that will show multiple rows for the same person for various reasons.
There is a column called college_attend which will show either New or Cont for each student.
My issue: my initial query narrows down the rows I'm pulling by Academic Year, which consists of two semesters: Fall of one year, and Spring of the following to create an academic year. This is why there are two rows returned for some students.
Basically, I need to generate an accurate count of those that are "New" and those that are "Cont", but I don't want both records for the same student counted. They will have two records because they will have one for spring and one for fall (usually). So if a student is "New" in fall, they will have a "Cont" record for spring. I want the query to show ONLY the "New" record if they have both a "New' and "Cont" record, and count it (which I will do in Report Builder). The other students will basically have two records that are "Cont": one for fall, and one "Cont" for spring, and so those would be considered the continuing ones or "Cont".
Here is the basic query I have so far:
SELECT DISTINCT
people.people_id,
people.last_name,
people.first_name,
academic.college_attend AS NewORCont,
academic.academic_year,
academic.academic_term,
FROM
academic
INNER JOIN
people ON people.people_id = academic.people_id
INNER JOIN
academiccalendar acc ON acc.academic_year = academic.academic_year
AND acc.academic_term = academic.academic_term
AND acc.true_academic_year = #Academic_year
I'm not sure if this can be done with a CASE statement? I thought of a GROUP BY, but then SQL Server will want me to add all of my columns to the GROUP BY clause, and that ends up negating the purpose of the grouping in the first place.
Just a sample of what I work with for each student:
People ID
Last
First
NeworCont
12345
Soanso
Guy
New
12345
Soanso
Guy
Cont
32345
Person
Nancy
Cont
32345
Person
Nancy
Cont
55555
Smith
John
New
55555
Smith
John
Cont
---------
------
-------
----------
Hopefully this sheds some light on the duplicate record issue I mentioned.
Without sample data its awkward to visualize the problem, and without the expected results specified it's also unclear what you want as the outcome. Perhaps this will assist, it will limit the results to only those who have both 'New' and 'Cont' in a single "true academic year" but the count seems redundant as this (I imagine) will always be 2 (being 1 New term and 1 Cont term)
SELECT
people.people_id
, people.last_name
, people.first_name
, acc.true_academic_year
, count(*) AS count_of
FROM academic
INNER JOIN people ON people.people_id = academic.people_id
INNER JOIN academiccalendar acc ON acc.academic_year = academic.academic_year
AND acc.academic_term = academic.academic_term
AND acc.true_academic_year = #Academic_year
GROUP BY
people.people_id
, people.last_name
, people.first_name
, acc.true_academic_year
HAVING MAX(academic.college_attend) = 'New'
AND MIN(academic.college_attend) = 'Cont'

Need help finding only Employees and Sales Persons in SQL

I am trying to run an SQL query which would fetch me all people who are
1. Only employees,
2. Employees and a sales person and
3. Only sales persons.
I am working on the Oracle E-Business Suite. So far, my query returns only those people who are employees only and those people who are employees and also a sales person. Here is what I've managed so far:
select distinct PAF.LAST_NAME,
PAF.START_DATE "HIRE_DATE",
PAF.EMPLOYEE_NUMBER,
PPT.SYSTEM_PERSON_TYPE "PERSON_TYPE",
JRS.SALES_CREDIT_TYPE_ID,
JRS.SALESREP_NUMBER
from PER_ALL_PEOPLE_F PAF,
PER_PERSON_TYPES PPT,
PER_PERSON_TYPE_USAGES_F PPTU,
JTF_RS_DEFRESOURCES_VL JRDV,
JTF_RS_SALESREPS JRS
where PAF.PERSON_ID = PPTU.PERSON_ID
and PPTU.PERSON_TYPE_ID = PPT.PERSON_TYPE_ID
and PPT.SYSTEM_PERSON_TYPE in ('EMP','OTHER')
and JRDV.category in ('EMPLOYEE','OTHER')
and (JRS.SALESREP_NUMBER(+) = PAF.EMPLOYEE_NUMBER)
and sysdate between PAF.EFFECTIVE_START_DATE and PAF.EFFECTIVE_END_DATE;
This is what I want to achieve
I have to include those people who are ONLY salespersons. Basically, there should be some rows which have no Employee_Number but only SALESREP_NUMBER. What am I doing wrong?
Pretty sure your issue lies here:
AND PAF.EMPLOYEE_NUMBER = JRS.SALESREP_NUMBER
Like the comment above says, you don't give much info. But, an educated guess would be that the equivalence indicated above would make that person an employee AND a salesperson. Maybe something more like:
AND (
PAF.EMPLOYEE_NUMBER = JRS.SALESREP_NUMBER
OR
( PAF.EMPLOYEE_NUMBER AND JRS.SALESREP_NUMBER IS NULL)
OR
( PAF.EMPLOYEE_NUMBER IS NULL AND JRS.SALESREP_NUMBER)
)
Or maybe just delete that clause?

SQL - count occurrences of gender

I'm new to SQL and I am creating a movie rental site database. I have to show some summary statistics of the database, so I'm planning to show the number of males and females that have selected films of a certain certification to rent.
The output I want is:
Certificate No. Males No. Females
----------- --------- -----------
U # #
PG # #
12 # #
15 # #
18 # #
The relevant tables for this query are:
FILM {FID (PK), Film_Title, Certificate, Date_of_Release}
MEMBER {MID (PK), ..., Gender}
LIST {MID (FK), FID (FK)}
FILM and MEMBER table should be quite self-explanatory, while a LIST is a selection of films a MEMBER wishes to rent. It's like a shopping basket, if you like. Each member only has one list and each list can contain many films. I tried to come up with a query but Access wouldn't let me run it:
SELECT Gender, COUNT(*) AS Gender_per_Certificate
FROM (SELECT DISTINCT Film_Title, Certificate, Gender
FROM (SELECT *
FROM Film, Member, List
WHERE Film.FID=List.FID
AND Member.MID=List.MID)
WHERE Film_Title IN (SELECT Film_Title
FROM (SELECT *
FROM Film, Member, List
WHERE Film.FID=List.FID
AND Member.MID=List.MID)
WHERE Certificate=[Certificate?]
GROUP BY Certificate))
WHERE (((Member.[Gender])="M")) OR ((("F")<>False))
GROUP BY Gender;
The error is
You tried to execute a query that does not include the specified expression 'FID' as part of an aggregate function
I'm not sure what this error means - could someone please explain it? Also, how can I execute the query correctly?
I understand this might be a really simple query that I've overcomplicated, would appreciate any help at all, thanks a lot for your time in advance!
If you use a case statement (IIF in access, thank you #HansUp) to determine which are male and female, grouping by certificate, you should get your answer.
select
f.Certificate,
sum(IIF(m.[gender] = 'M',1, 0)) as [# of males],
sum(IIF(m.[gender] = 'F',1, 0)) as [# of females]
from
(member m
inner join list l on m.mid = l.mid)
inner join film f on l.fid = f.fid
group by f.Certificate

Advanced Ordering Or Grouping Of Query Results (having?), Access 2013

I REALLY need help.
I have a list of faculty members that can either be in assigned to a department or just affiliated with the department.
I am trying to query but order the results so that any faculty that appear in the specified department appear in the list first, while anyone affiliated with the specified department are at the bottom of the queried results.
I want the affiliated faculty to be at the bottom of the query results!
Here is my example:
I am querying Philosophy, 20 faculty members are displayed, alphabetically but in no particular order and the results include ANYONE who has Philosophy in Dept 1 or Dept 2 of their record AND anyone who is simply Affiliated with the department. Some are in the actual department (Dept 1 or Dept 2 fields) but others are just affiliated with the department (Affiliation 1 - 5 fields) all interdispersed.
Now I want the query results to be ordered to show: faculty who have DEPT 1 or DEPT 2 = Philosophy, and any faculty that have Affiliations = Philosophy to be at the bottom of the list by themselves.
How do I do this? I've tried Order By and Having, I've tried Group By... Nothing seems to work the way I want it to.. I don't think I am using the write code.
Please, please help me. I've been stuck on this for hours.
Please help - here's my query code:
SELECT listOfAllFaculty.[ID], listOfAllFaculty.[lastName], listOfAllFaculty.[firstName], listOfAllFaculty.[middleInitialMiddleName], listOfAllFaculty.[position], listOfAllFaculty.[emeritusPosition], listOfAllFaculty.[department1], listOfAllFaculty.[department2], listOfAllFaculty.[school1], listOfAllFaculty.[school2], listOfAllFaculty.[affiliation1], listOfAllFaculty.[affiliation2], listOfAllFaculty.[affiliation3], listOfAllFaculty.[affiliation4], listOfAllFaculty.[affiliation5], listOfAllFaculty.[degree], listOfAllFaculty.[specialty], listOfAllFaculty.[awards], listOfAllFaculty.[other]
FROM listOfAllFaculty
WHERE (((listOfAllFaculty.department1)=[Type Department1])) Or (((listOfAllFaculty.department2)=[Type Department2])) Or (((listOfAllFaculty.affiliation1)=[Type Affiliation1])) Or (((listOfAllFaculty.affiliation2)=[Type Affiliation2])) Or (((listOfAllFaculty.affiliation3)=[Type Affiliation3])) Or (((listOfAllFaculty.affiliation4)=[Type Affiliation4])) Or (((listOfAllFaculty.affiliation5)=[Type Affiliation5]))
Perhaps this is what you're looking for using iif in your order by clause:
SELECT listOfAllFaculty.[ID], listOfAllFaculty.[lastName], ...
FROM listOfAllFaculty
WHERE (((listOfAllFaculty.department1)=[Type Department1])) Or
(((listOfAllFaculty.department2)=[Type Department2])) Or
(((listOfAllFaculty.affiliation1)=[Type Affiliation1])) Or
(((listOfAllFaculty.affiliation2)=[Type Affiliation2])) Or
(((listOfAllFaculty.affiliation3)=[Type Affiliation3])) Or
(((listOfAllFaculty.affiliation4)=[Type Affiliation4])) Or
(((listOfAllFaculty.affiliation5)=[Type Affiliation5]))
ORDER BY
IIF(listOfAllFaculty.department1=[Type Department1],0,
IIF(listOfAllFaculty.department2=[Type Department2],0,1))

How to find the number of students who got full mark in all exams from the first time of taking the exams?

I have the following part of database design where I need to find the list of students who got full mark in the popup exams from the first time of taking the exam. In details, let us assume we have three Students who took the first popup exam (Exam101) twice on different dates (or days):
Student A: first time, he got 0
Student A: second time, he got 10
Student B: first time, he got 10
Student C: first time, he got 10
Student C: second time, he got 0
The total number of students who took all the exams and got full mark from the first time of taking it should be: 2
The design I have for database is:
Students Table: StudentNo, Name, Year
Exams Table: ExamID, Title, ExamDate
StudentsExams Table: ID, ExamID, StudentNo, Score, CompletedON
So who can I find this result?
If a full mark is always 10 (for all exams) you can use:
select s.studentno,
s.name,
s.year,
se.examid,
e.title,
se.score,
se.completedon
from students s
join studentsexams se
on s.studentno = se.studentno
join exams e
on se.examid = e.examid
join (select studentno, examid, min(completedon) as first_completed
from studentsexams
group by studentno, examid) v
on se.examid = v.examid
and se.studentno = v.studentno
and se.completedon = v.first_completed
where se.score = 10
If what constitutes a "full mark" varies by exam we need to know how to determine what the max score is for each exam. Your exams table does not seem to have a max score field, based on what you posted.
with cte_num
as
(
select name,ExamID,count(CompletedON)
from Students s join StudentsExams se
on s.StudentNo=se.StudentNo
join Exams e
on e.ExamID=se.ExamID
where score=10
having count(CompletedON)=1)
select count * from cte_num