I have 2 tables "Staffs" and "Staffjoins",
In Staffs:
two columns:
"sid"- teacher ID (primary Key)
"Sname"- Name of Teacher
In Staffjoins:
three columns
"sid"-teacher ID foreign key (refrences from Staffs table)
"cname" - college name,
"Salary" - teacher salary
My Question is:
I am entering 10 rows in staffs with unique sid and also enter sname with sid.
Then I enter 10 rows in staffjoins table where I entered:
3 rows with cname="College1",
2 rows with cname="College2",
2 rows with cname="College3",
3 rows with cname="College4".
In all rows have "salary" and different sid also then I want to take the name of teacher who earn the highest salary of each College with college name.
Salary is in the wrong table, and there should be a colleges table.
Best you can do is something like this.
Select c.cname, t.Sname
From StaffJoins c
Inner join (Select cname, Max(Salary) as Salary From StaffJoins) as biggestearners
on biggestearners.cname = c.name and biggestearners.salary = c.salary
inner join Staff t on c.sid = t.sid
Related
I have three tables I want to iterate over. The tables are pretty big so I will show a small snippet of the tables. First table is Students:
id
name
address
1
John Smith
New York
2
Rebeka Jens
Miami
3
Amira Sarty
Boston
Second one is TakingCourse. This is the course the students are taking, so student_id is the id of the one in Students.
id
student_id
course_id
20
1
26
19
2
27
18
3
28
Last table is Courses. The id is the same as the course_id in the previous table. These are the courses the students are following and looks like this:
id
type
26
History
27
Maths
28
Science
I want to return a table with the location (address) and the type of courses that are taken there. So the results table should look like this:
address
type
The pairs should be unique, and that is what's going wrong. I tried this:
select S.address, C.type
from Students S, Courses C, TakingCourse TC
where TC.course_id = C.id
and S.id = TC.student_id
And this does work, but the pairs are not all unique. I tried select distinct and it's still the same.
Multiple students can (and will) reside at the same address. So don't expect unique results from this query.
Only an overview is needed, so that's why I don''t want duplicates
So fold duplicates. Simple way with DISTINCT:
SELECT DISTINCT s.address, c.type
FROM students s
JOIN takingcourse t ON s.id = t.student_id
JOIN courses c ON t.course_id = c.id;
Or to avoid DISTINCT (why would you for this task?) and, optionally, get counts, too:
SELECT c.type, s.address, count(*) AS ct
FROM students s
JOIN takingcourse t ON s.id = t.student_id
JOIN courses c ON t.course_id = c.id
GROUP BY c.type, s.address
ORDER BY c.type, s.address;
A missing UNIQUE constraint on takingcourse(student_id, course_id) could be an additional source of duplicates. See:
How to implement a many-to-many relationship in 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?
So I have three tables: Employee, Secretary and Manager
Given Schema
The Employee table has the following columns:
Employee_Number
Name
Home Address
Telephone Number
The Secretary table contains:
Secretary_Number
Employee_Number (linked with foreign key to Employee table)
Manager_Number (linked with foreign key to Manager table)
The Manager table contains:
Manager_Number
Employee_Number (linked with foreign key to Employee table)
What's required and what I tried
I am trying to do a JOIN so that I can see following columns:
Secretary's Number
Secretary's Name
Manager's Number
Manager's Name
I have the following join statement, which shows all the columns, and shows the Secretary's name and number, as well as the Manager Number:
SELECT
SECRETARY.SECRETARY_NUMBER,
SECRETARY.EMPLOYEE_NUMBER AS SECRETARY_EMPLOYEE,
EMPLOYEE.NAME AS SECRETARY_NAME,
SECRETARY.MANAGER_NUMBER,
MANAGER.EMPLOYEE_NUMBER AS MANAGER_EMPLOYEE,
EMPLOYEE.NAME AS MANAGER_NAME
FROM SECRETARY, MANAGER, EMPLOYEE
WHERE SECRETARY.MANAGER_NUMBER = MANAGER.MANAGER_NUMBER
AND SECRETARY.SECRETARY_NUMBER = EMPLOYEE.EMPLOYEE_NUMBER
AND MANAGER.EMPLOYEE_NUMBER = EMPLOYEE.EMPLOYEE_NUMBER;
Problem
But I can't get the Manager's Name to show up, or not repeat the same info as Secretary Name.
Any help would be greatly appreciated!
SELECT
s.SECRETARY_NUMBER,
s.EMPLOYEE_NUMBER AS SECRETARY_EMPLOYEE,
e.NAME AS SECRETARY_NAME,
s.MANAGER_NUMBER,
m.EMPLOYEE_NUMBER AS MANAGER_EMPLOYEE,
e2.NAME AS MANAGER_NAME
FROM
SECRETARY s
INNER JOIN
EMPLOYEE e
ON
e.EMPLOYEE_NUMBER = s.EMPLOYEE_NUMBER
INNER JOIN
MANAGER m
ON
m.EMPLOYEE_NUMBER = s.MANAGER_NUMBER
INNER JOIN
EMPLOYEE e2
ON
e2.EMPLOYEE_NUMBER = m.EMPLOYEE_NUMBER;
I have two tables one is teacher and another is Department which is mentioned below.
Teacher Table
Id Name
1 xyz
2. Gjd
3. Dftr
4 dhdk
Department Table
Id Name EMPID
1 SQL. 2
2. PHP. 4
3. JAVA. 1
4 PEARL. 5
QUESTION
i want those records of teacher which are not link with any Department.
you can use following statement using left join then filter Teacher that not matched
SELECT t.*
FROM Teacher t
left join Department d on d.EMPID = t.Id
where d.id is null
SELECT * FROM teachers WHERE
id NOT IN (SELECT DISTINCT EMPID FROM departments) ;
Hope this helps.!!
you can do it by inner query..
select * from teacher where id not in (select empid from department);
I have a database table like that
Table student
_______________
id_student int (PK)
student_name VARCHAR
and I have a recursive loop:
A student can oversee many students, and a student can be overseen by many students
so a new table:
Table oversee
________________
id_student pk, fk
id_overseen pk, fk
date date
the problem is that I want to get the list that I have
I made an sql query:
with
sr1 as ( select s.student_name as over from student s, oversee o where o.id_student = s.id_student),
sr2 as (select s.student_name as overseen from student s, oversee o where o.id_overseen = s.id_student)
select distinct * from sr1, sr2;
the problem is that's the query returns the wrong answers
I mean if we have two lines in the table, it will return 4 lines.
I want to get every student with his overseen:
Student | overseen.
Someone has any idea please?
Thanks.
I want to get a table with student | overseen | date
SELECT s.student_name AS student
, s2.student_name AS overseen
, oversee.date
FROM student s
JOIN oversee ON oversee.id_student = s.id_student
JOIN student s2 ON s2.id_student = oversee.id_overseen