I have a one to many relationship between departments and users.
Database Design:
users has each own department and department has many users. I wanted to select all the department_name but I have a duplicate values of department_name I want to merge it into one so I planned to use UNION how can I implement this using Inner Join? This is my code so far.
SQL
SELECT D.department_name FROM users U
INNER JOIN departments D ON D.id = U.department_id;
Results:
If you want only the distinct department names, you need to group the users into a comma separated values.
select d.department_name, group_concat(u.id) user_id_list
from departments d inner join users u on d.department_id = u.department_id
group by d.department_name
Related
Right now i have these two tables
doctor_id and their appointment count
and doctor name and his/her department name
I need to count every department appointments any idea how to connect these two tables ?
Just join all the tables and change the grouping.
SELECT d.name AS department, COUNT(r.d_id) AS appointment_count
FROM departments AS d
JOIN userdelprel AS ud ON d.dept_id = ud.dept_id
JOIN users AS u ON u.u_id = ud.u_id
LEFT JOIN roomreservations AS r ON r.d_id = u.u_id
WHERE u.role_id = 2
GROUP BY d.dept_id
The question is stated as there is a database on professors, departments, courses and schedules. Need to write a query that returns the names of all the professors and their respective courses. Each row must contain the name of the professor followed by the name of the course that the professor teaches. There must be no duplicates in terms of the rows.
The schema I have, in terms of the table name and the fields:
PROFESSOR: ID, NAME, DEPARTMENT_ID, SALARY
DEPARTMENT: ID, NAME
COURSE: ID, NAME, DEPARTMENT_ID, CREDITS
SCHEDULE: PROFESSOR_ID, COURSE_ID, SEMESTER, YEAR
The code I have right now:
SELECT DISTINCT p.Name AND c.NAME
FROM Prodessor p, Course c, Schedule S
WHERE
p.DEPARTMENT_ID = c.DEPARTMENT_ID
AND
p.ID = s.PROFESSOR_ID
AND
c.ID = c.COURSE_ID
The result I get is a list of all professors, but there aren't multiple courses, just a single one. What's going wrong here? It also mentioned that PROFESSOR.ID is foreign to COURSE.PROFESSOR_ID, so p.ID = s.PROFESSOR_ID is valid
I think the below code will solve your requirement
SELECT distinct p.name,c.name
from Professor p
inner join Schedule s on p.id=s.professor_id
inner join course c on c.id=s.course_id;
Alternatively if we want professors with the names of the courses they teach (or have taught) outside of their department.
select distinct p.name, c.name
FROM professor p
JOIN schedule s on s.professor_id = p.id
JOIN course c on s.course_id = c.id
WHERE c.department_id <> p.department_id;
seems you need left join instead of inner join. i think you don't need distinct() with this kind of information
select distinct p.Name, c.Name, s.*
from schedules s
left join Professor p on p.id = s.professor_id
inner join Department d on d.department_id = p.department_id
left join Course c on s.course_id= c.id
but if you only want professor and course info, assuming there's some professors that doesn't have schedules yet.
so no course info yet.
select distinct p.Name, c.Name
from Professor s
left join Course c on c.professor_id = p.id
I would use a left join here, and only involve the professor and course tables.
SELECT
p.NAME,
COALESCE(c.COURSE_ID, 'no courses available') AS COURSE_ID
FROM PROFESSOR p
LEFT JOIN COURSE c
ON p.ID = c.PROFESSOR_ID
ORDER BY
p.NAME;
The left join option lets us display a message should a given professor have no courses associated with him.
This was probably asked a few times, but I couldn't find an answer. While doing JOIN on two tables, I encounter a problem.
First table is named "Employees" and another "Orders".
I'm trying to create a query, which will give me the output like:
order_id (from Orders) | first_name (from Employees) | last_name (from Employees)
The queries I use are:
SELECT * FROM Orders
LEFT JOIN Employees e on Orders.employeeid = e.EmployeeID;
or full join:
SELECT * FROM Orders
LEFT JOIN Employees e on Orders.employeeid = e.EmployeeID
UNION
SELECT * FROM Employees
RIGHT JOIN Orders o on Employees.EmployeeID = o.employeeid;
both work just fine, giving me the same results. Unless I select which columns I wish to extract. So query like that:
SELECT Orders.orderid, e.first_name, e.last_name FROM orders
LEFT JOIN Employees e on orders.employeeid = e.EmployeeID;
Gives me totally different results. Eg. first 100 orderids have same employee name, then another 100 different one and so on (only 4 employees overall, should be 9).
What am I doing wrong?
EDIT (screenshots added):
Orders table:
Employees table:
Output when doing full join, everything seems to be ok:
Left join (or any other join, looks the same). Some orders seem to be ommited, but overall only 4 employees are listed.
I don't know your data, but I think you want:
SELECT o.orderid, e.first_name, e.last_name FROM orders o INNER JOIN Employees e ON o.employeeid = e.employeeId
where o.employeeid != null
Order by o.orderid
It's hard to tell without seeing some data samples.
But here are a few points:
With LEFT JOIN you get 'only 4 employees overall, should be 9' -- I assume there are 5 employees that do not have any order.
In the 'full join' you get mixed columns, the correct way should be
SELECT * FROM Orders
LEFT JOIN Employees e on Orders.employeeid = e.EmployeeID
UNION
SELECT * FROM Orders
RIGHT JOIN Employees e on Orders.employeeid = e.EmployeeID
Otherwise there should be no difference in the output if you specify the columns, as opposed to *.
If
SELECT * FROM Orders
LEFT JOIN Employees e on Orders.employeeid = e.EmployeeID
is returning the correct set of results, then this should probably work:
Select orderid, FirstName, LastName from (SELECT * FROM Orders
LEFT JOIN Employees e on Orders.employeeid = e.EmployeeID LIMIT 999999) as joinedTable
SELECT
e.lname AS employee_name
, s.lname AS supervisor_name
, e.superssn AS supervisor_ssn
FROM employee e INNER JOIN employee s
WHERE e.superssn=s.ssn
I actually have two questions. The first one is, the above statement works just fine. However right now it will show bunch of employees with their supervisor. Not well organized. By the way there are three supervisors. Is there a way to show let's say supervisor A with employees A and supervisor B with employees B and so on?
The second problem is that I also tried to just count the number of employees for each supervisor rather than showing their name with COUNT(), I tried several different ones but non worked.
A few things
1) It is good practice to keep your join predicate with your join. So change:
FROM employee e INNER JOIN employee s WHERE e.superssn = s.ssn
To:
FROM employee e INNER JOIN employee s ON e.superssn = s.ssn
2) To keep them together by supervisor, just use an order by:
SELECT
e.lname AS employee_name
, s.lname AS supervisor_name
, e.superssn AS supervisor_ssn
FROM employee e INNER JOIN employee s ON e.superssn = s.ssn
ORDER BY s.lname
3) To do a count of employees for each supervisor use a group by and the COUNT aggregate function
SELECT
s.lname AS supervisor_name,
COUNT(*) AS employee_count
FROM employee e INNER JOIN employee s ON e.superssn = s.ssn
GROUP BY s.lname
ORDER BY s.lname
I have a users table which contains the users information (fname, lname...etc) and a invoices table. In the invoices table I have a field called created_id which links to the user.id that created the invoice. I also have a field called staff_id which links to the staff user.id that approved the invoice.
How can I query the first and last name for both the created_id and the staff_id in a single query? Here are a few things I've tried....
SELECT
invoices.*,
users.fname as created_fname,
users.lname as created_lname
FROM
invoices
INNER JOIN users
ON users.id = invoices.created_id;
This works, but it only gets me the person's name that created the invoice. How can I add the staff's name to that as well....
SELECT
invoices.*,
users.fname as created_fname,
users.lname as created_lname,
users2.fname as staff_fname,
users2.lname as staff_lname
FROM invoices, users
LEFT JOIN
invoices,
users AS users2
ON
users.id = invoices.created_id,
users.id = users2.id
That doesn't work, but is closer. Any guidance or examples would be very helpful. Also, if you have any recommendations for good books on learning how to do more advanced MySQL queries that would be helpful too.
You need to join users table twice on table Invoice.
SELECT a.*,
b.fname created_firstName,
b.lname created_LastName,
c.fname staff_firstName,
c.lname staff_LastName
FROM Invoice a
INNER JOIN users b
ON a.created_id = b.id
INNER JOIN users c
ON a.staff_id = c.id
and best thing is you can concatenate their names into one using CONCAT
SELECT a.*,
CONCAT(b.fname, ' ', b.lname) created_fullName,
CONCAT(c.fname, ' ', c.lname) staff_fullName
FROM Invoice a
INNER JOIN users b
ON a.created_id = b.id
INNER JOIN users c
ON a.staff_id = c.id