Incorrect Command (INSERT INTO ... SELECT with GROUP BY) - sql

The exercise for my online course is as follows
This time, the university needs a list of average results of written and oral exams in each subject (from the exam table).
The new table, report_average_scores consists of the following columns: subject, avg_written_exam_score, and avg_oral_exam_score (which are of type DECIMAL(4,2)).
Help the university insert data into the report_average_scores table.
I have attempted adding the GROUP BY as I should, but I am unable to pass the section. Also, I can not find where the decimal would play part.
INSERT INTO report_average_scores
(
subject,
avg_written_exam_score,
avg_oral_exam_score
)
SELECT
subject,
written_exam_score,
oral_exam_score
FROM exam;
I expect the output to approve the code, but I am running into the same error.

Am I seeing it wrong or you just need to average?
SELECT
subject,
AVG(written_exam_score),
AVG(oral_exam_score)
FROM exam group by subject

Related

How to get rolling unique count of employees per year based on key fields

I have the following table and I wanted to get the running unique count by dept, team, level. But the cumulative unique count will restart per year.
Note: sorry in my main table example, employee numbers may repeat up to four times. There is another column called leave type but wasn't able to illustrate it in the image
Main table
Expected output would be something like below.
Expected output
Is this possible? Apologies. Not too advanced when it comes to SQL. Thank you.
You can do:
select max(extract(year from date)), date, department, level, team, count(*)
from t
group by date, department, level, team

what does Group By multiple columns means?

I use oracle 11g , so i read alot of artics about it but i dont understand
how exactly its happened in database , so lets say that have two tables:
select * from Employee
select * from student
so when we want to make group by in multi columns :
SELECT SUBJECT, YEAR, Count(*)
FROM Student
GROUP BY SUBJECT, YEAR;
so my question is: what exactly happened in database ? i mean the query count(*) do first in every column in group by and then sort it ? or what? can any one explain it in details ?.
SQL is a descriptive language, not a procedural language.
What the query does is determine all rows in the original data where the group by keys are the same. It then reduces them to one row.
For example, in your data, these all have the same data:
subject year name
English 1 Harsh
English 1 Pratik
English 1 Ramesh
You are saying to group by subject, year, so these become:
Subject Year Count(*)
English 1 3
Often, this aggregation is implemented using sorting. However, that is up to the database -- and there are many other algorithms. You cannot assume that the database will sort the data. But, if it easier for you to think of it, you can think of the data being sorted by the group by keys, in order to identify the groups. Just one caution, the returned values are not necessarily in any particular order (unless your query includes an order by).

Retrieving duplicate and original rows from a table using sql query

Say I have a student table with the following fields - student id, student name, age, gender, marks, class.Assume that due to some error, there are multiple entries corresponding to each student. My requirement is to identify the duplicate rows in the table and the filter criterion is the student name and the class.But in the query result, in addition to identifying the duplicate records, I also need to find the original student detail which got duplicated. Is there any method to do this. I went through this answer: SQL: How to find duplicates based on two fields?. But here it only specifies how to find the duplicate rows and not a means to identify the actual row that was duplicated. Kindly throw some light on the possible solution. Thanks.
First of all: if the columns you've listed are all in the same table, it looks like your database structure could use some normalization.
In terms of your question: I'm assuming your StudentID field is a database generated, primary key and so has not been duplicated. (If this is not the case, I think you have bigger problems than just duplicates).
I'm also assuming the duplicate row has a higher value for StudentID than the original row.
I think the following should work (Note: I haven't created a table to verify this so it might not be perfect straight away. If it doesn't it should be fairly close)
select dup.StudentID as DuplicateStudentID
dup.StudentName, dup.Age, dup.Gender, dup.Marks, dup.Class,
orig.StudentID as OriginalStudentId
from StudentTable dup
inner join (
-- Find first student record for each unique combination
select Min(StudentId) as StudentID, StudentName, Age, Gender, Marks, Class
from StudentTable t
group by StudentName, Age, Gender, Marks, Class
) orig on dup.StudentName = orig.StudenName
and dup.Age = orig.Age
and dup.Gender = orig.Gender
and dup.Marks = orig.Marks
and dup.Class = orig.Class
and dup.StudentID > orig.StudentID -- Don't identify the original record as a duplicate

Oracle SQL, not exist and count

I am currently stuck with my assignment. I am not trying to be lazy but I can't seems to find a solution and my teacher guided me by saying to use not exist or count.
I need to find patients name who have been treated by all the doctors. Currently I am just using plain intersect SQL command for each doctor name (In the question, there are only 3 doctors) but of course its not realistic when there are 100's of doctors name.
The scheme is as below.
Patient (PatientID, FamilyName, GivenName)
Account (ProviderNo, PatientID)
Doctor (ProviderNo, Name)
Any help would be greatly appreciated.
I won't provide you the exact Query.
But here is the psuedo code:
group PatientId in Account where its distinct ProviderNo count should be
equal to no. of Doctors

Counting database items with join

Using ORMLite, I want to count the number of database items that fit certain criteria. A simplified version of my database is as follows:
Employee Table:
employeeId
departmentId
Department Table:
departmentId
Salary Table:
employeeId
payGrade
Suppose I want to count the number of employees from a subset of departments that are at certain pay grade. When I try something like the following, I get an exception reporting that only one select column is allowed.
salaryQB.selectColumns(salaryQB.EMPLOYEE_ID);
salaryQB.where().eq(salaryQB.PAY_GRADE, 12);
employeeQB.where.in(Employee.DEPARTMENT_ID, departmentList)
.and().in(employeeQB.EMPLOYEE_ID, salaryQB);
employeeQB.setCountOf(true);
count = dao.countOf(employeeQB.prepare());
But code like this returns the following error:
RuntimeException (java.sql.SQLException: Inner query must have only 1
select column specified instead of 2)
Is there any way to do this short of writing a raw SQL query?
Hrm. I can't see any problems with your code #Jeff. I've improved the exception message in ORMLite to show the actual field names for the future but that won't help you right now:
Inner query must have only 1 select column specified instead of 2: [id, foreign]
The message is [obviously] trying to tell you that you have specified more than one selectColumns(...) in the salaryQB inner QueryBuilder. But you seem to be only selecting one column here:
salaryQB.selectColumns(salaryQB.EMPLOYEE_ID);
I don't see where the salaryQB is defined but maybe there is some more code somewhere else that also is using selectColumns? I've tried to reproduce the error in the testInnerCountOf() method towards the bottom of the QueryBuilderTest unit test but it seems to work fine.
If you can reproduce this in a unit test or if you can see how my unit test differs from your config then let me know.
Edit:
As of version 4.22 (from 9/2012), ORMLite now supports simple JOIN statements. So your query can be simplified to:
salaryQB.where().eq(salaryQB.PAY_GRADE, 12);
employeeQB.join(salaryQB);
employeeQB.where().in(Employee.DEPARTMENT_ID, departmentList);
employeeQB.setCountOf(true);
count = dao.countOf(employeeQB.prepare());