Condition for finding rows with same value in one colum and null in another column - sql

I have a table with columns student ID, subject, Enrolled. I have a row for each subject against a student. I am inserting this data to a temp table for reporting. I have another column named reporting in this temp table. I need to update reporting false when enrolled is null for all the rows imported for a student.

Here is the approach:
Select from all students
Left outer join to student-course (outer join is important here)
Group by student ID, and get min course ID
Use rows with null course ID to decide what temp rows to update
In SQL this query would look like this:
SELECT StudentId, MIN(CourseId)
FROM Student s
LEFT OUTER JOIN StudentCourse sc
ON s.StudentId=sc.StudentId
GROUP BY s.StudentId
HAVING MIN(CourseId) IS NULL

Related

Create a additional row from join sql?

I have 2 tables: Person and House with 1-n relation.
I want to the result return as picture below:
Row always have a Person column with a null House column.
Thanks.
you can use unionall to join the result set with person table something like
select p.name,h.name as housename from person p join house h on p.id=h.personid
union all (select name,null from person)
order by name,housename

Update column in table2 based on select query which contains count() from table1 using postgresql

Tables
Need to update department table's dcount column based on number of employees working in each department from employee table's dno column.
Tried using
update department set dcount=(select count() from employee INNER JOIN department ON employee.dno=department.dnumber group by dno);*
which gave an error : more than one row returned by a subquery used as an expression
Desired result is:
**dname|dnumber|dcount
Research|5|4
Admin|4|3
Headquarters|1|1**
Need help please.
Thanks in advance.
Gruheeth
Your subquery (select count() ...) returns several rows, one per employee, where postgres expect only one row from this subquery in order to update one row at a time in the department table. In this case, you case use a cte instead :
WITH list AS
(
select dno, count(*) AS dno_count
from employee
group by dno
)
update department AS d
set dcount = l. dno_count
from list AS l
where d.dnumber = l.dno ;

INNER JOIN and Count POSTGRESQL

I am learning postgresql and Inner join I have following table.
Employee
Id Name DepartmentId
1 John S. 1
2 Smith P. 1
3 Anil K. 2
Department
Department
Id Name
1 HR
2 Admin
I want to query to return the Department Name and numbers of employee in each department.
SELECT Department.name , COUNT(Employee.id) FROM Department INNER JOIN Employee ON Department.Id = Employee.DepartmentId Group BY Employee.department_id;
I dont know what I did wrong as I am new to database Query.
When involving all rows or major parts of the "many" table, it's typically faster to aggregate first and join later. Certainly the case here, since we are after counts for "each department", and there is no WHERE clause at all.
SELECT d.name, COALESCE(e.ct, 0) AS nr_employees
FROM department d
LEFT JOIN (
SELECT department_id AS id, count(*) AS ct
FROM employee
GROUP BY department_id
) e USING (id);
Also made it a LEFT [OUTER] JOIN, to keep departments without any employees in the result. And COALESCE to report 0 employees instead of NULL in that case.
Related, with more explanation:
Query with LEFT JOIN not returning rows for count of 0
Your original query would work too, after fixing the GROUP BY clause:
SELECT department.name, COUNT(employee.id)
FROM department
INNER JOIN employee ON department.id = employee.department_id
Group BY department.id; --!
That's assuming department.id is the PRIMARY KEY of the table, in which case it covers all columns of that table, including department.name. And you may want LEFT JOIN like above.
Aside: Consider legal, lower-case names exclusively in Postgres. See:
Are PostgreSQL column names case-sensitive?

Selecting students who have not made any payment in a given period (term)

I have two tables: students and payments.
students has the columns:
first_name
last_name
student_id
class_name
payments table has the columns:
full_name
student_id
term
session
amount_paid
class_fee
The details of every student is in the students table, but only those who have made either full or part payment enters the payments table. I have written a query to select those who have paid.
The question now is how to write a query that will select those in a particular class that have made no payment at all in a given period (term).
You are probably using a JOIN to select those who have paid. That will work because there are matching rows in both tables. To find those who have not paid, you can use a LEFT JOIN. It will give you NULL if rows do not match.
SELECT students.*
FROM students
LEFT JOIN payments ON students.student_id = payments.student_id
AND term = 'whatever'
WHERE amount_paid IS NULL
(Note: the term = 'whatever' needs to be in the ON clause, not the WHERE)
You can also do this using a subquery and the NOT EXISTS clause. NOT EXISTS will return true if the subquery returns zero rows.
SELECT *
FROM students
WHERE NOT EXISTS(
SELECT amount_paid
FROM payments
WHERE students.student_id = payments.student_id
AND term = 'whatever'
)

SQL Join Issue with Nulls

I have 7 tables I am using in a view. For examples, I will be using these as my table names (The Fields within the table don't matter for this execpt that the PrimaryKey is tableName + ID)
Table 1.
Teacher
Table 2.
Student (Exception-- Student has all the ids in it, from all the other 6 tables)
Table 3.
Science
Table 4.
Math
Table 5.
History
Table 6.
German
Table 7.
Language Arts
Now, All the tables from 3-7 have a relationship to Student from Table 2. And Student has a relationship to teacher.
My view currently works if any of my tables have any fields. and some can be null, it also works if any of my tables 3-7 are completely null, it will still display.
However, my current problem is, if my teacher has no students assigned to them, making tables 2-7 null, empty, etc.... My query doesnt even return the teacher info that is filled in... First name, last name, Date of birth, etc.
How can I Accomplish this?
I tried doing all left joins from all the tables, since the teacher can have null fields, I tried doing an inner join from dbo.Teacher as Teacher Inner Join dbo.Student on dbo.Student.TeacherID = Teacher.TeacherID but that didnt work.. I am at a loss...
SELECT Teacher.TeacherID ,
Student.StudentID ,
Science.ScienceID ,
History.HistoryID ,
Math.MathID ,
German.GermanID ,
LanguageArts.LanguageArtsID
FROM dbo.Teacher AS Teacher
LEFT OUTER JOIN dbo.Student
ON dbo.Student.TeacherID = Teacher.TeacherID
LEFT OUTER JOIN dbo.Science AS Science
ON dbo.Student.ScienceID = Science.ScieneID
LEFT OUTER JOIN dbo.Math AS Math
ON dbo.Student.MathID = Math.MathID
LEFT OUTER JOIN dbo.History AS History
ON dboStudent.HistoryID = History.HistoryID
LEFT OUTER JOIN dbo.German AS German
ON dbo.Student.GermanID = German.GermanID
LEFT OUTER JOIN dbo.LanuageArts AS LanguageArts
ON dbo.Student.LanguageArtsID = LanguageArts.LanguageArtsID
Two comments:
Do you know the use of LEFT JOIN?. This query should return all teachers, even thouse with no students.
SELECT *
FROM teacher t LEFT JOIN student s ON s.teacher_id = t.id
(RIGHT JOIN would work if you want all student even if they do not have teachers)
Remmember that in SQL 1 == NULL and 1 != NULL are both false. So the following query will not result a teacher without students or a student without teachers.
SELECT *
FROM teacher t,
student s
WHERE s.teacher_id = t.id
I figured out my answer, in my select i was using dbo.Student.TeacherID, instead of dbo.Teacher.TeacherID, therefore my query was always coming back with null TeacherID values since I was checking my view with a query like this one
Select * from MyView Where TeacherID = 1;
This returned null since my select was pulling Student.TeacherID which is null, so I Swapped out dbo.Student.TeacherID for dbo.Teacher.TeacherID and it is now resolved.
Such a bleh moment. Thanks for comments and replies.!
As I am reading back in my OP, I said I was selecting
SELECT Teacher.TeacherID ,
Student.StudentID ,
which was technically a typo, but also my answer...