Reputation: 139
I'm having an error when executing the query. I don't know what seems to be the problem. I'm trying to query the DB to to find out the staffs from two or more departments. (ie. Staff_ID = 1, works under the DEPT_ID = 4, and 6). There are three tables involved:
1. STAFF
2. DEPARTMENT
3. STAFF_DEPT (contains ID of STAFF and DEPT)
Here's what I've done,
SELECT
sd.STAFF_ID || ' ' || s.STAFF_NAME AS "Staff Name",
d.DEPT_NAME AS "Department"
FROM STAFF_DEPT sd
INNER JOIN STAFF s ON sd.STAFF_ID = s.STAFF_ID
INNER JOIN DEPARTMENT d ON sd.DEPT_ID = d.DEPT_ID
GROUP BY sd.STAFF_ID
HAVING COUNT (sd.STAFF_ID) > 1
Upvotes: 0
Views: 1069
Reputation: 1269693
Here is your original query:
SELECT sd.STAFF_ID || ' ' || s.STAFF_NAME AS "Staff Name",
d.DEPT_NAME AS "Department"
FROM STAFF_DEPT sd
INNER JOIN STAFF s ON sd.STAFF_ID = s.STAFF_ID
INNER JOIN DEPARTMENT d ON sd.DEPT_ID = d.DEPT_ID
GROUP BY sd.STAFF_ID
HAVING COUNT (sd.STAFF_ID) > 1;
The problem with your query is that you are doing an aggregation on staff_id
, but you have the columns staff_name
and dept_name
in your aggregation. You are looking for staff in multiple departments. You can get one row per person with a list of departments using:
SELECT sd.STAFF_ID || ' ' || s.STAFF_NAME AS "Staff Name",
list_agg(d.DEPT_NAME, ',') within group (order by DEPT_NAME) AS "Department_List"
FROM STAFF_DEPT sd
INNER JOIN STAFF s ON sd.STAFF_ID = s.STAFF_ID
INNER JOIN DEPARTMENT d ON sd.DEPT_ID = d.DEPT_ID
GROUP BY sd.STAFF_ID, s.STAFF_Name
HAVING COUNT (sd.STAFF_ID) > 1;
Notice: I've adding list_agg()
in the select
and s.staff_name
in the group by
.
If you want one person/department per row, then use a subquery with an analytic function:
selectsd.STAFF_ID || ' ' || s.STAFF_NAME AS "Staff Name", dept_name
from (select sd.staff_id, s.staff_name, d.dept_name,
count(*) over (partition by sd.staff_id, s.staff_name) as NumDepts
FROM STAFF_DEPT sd
INNER JOIN STAFF s ON sd.STAFF_ID = s.STAFF_ID
INNER JOIN DEPARTMENT d ON sd.DEPT_ID = d.DEPT_ID
) t
where NumDepts > 1;
Upvotes: 2
Reputation: 123
Try this one:
with temp as
(select sd.staff_id from staff_dept sd
group by staff_id
having count(staff_id)>1)
select tp.staff_id||' ' ||s.Name AS "Staff Name", d.DNAME
FROM temp tp,
staff_dept sd,
staff s,
dept d
where tp.staff_id=sd.staff_id
and sd.staff_id=s.id
and sd.dept_id=d.deptno;
I have stored the staff_id's having count more than 1 in a temporary view and used it in the final select query.
As I have previously mentioned to techdo that you cannot group by sd.STAFF_ID || ' ' || s.STAFF_NAME, d.DEPT_NAME as it would always be unique and would have count as 1 always.
Upvotes: 1
Reputation: 18629
Please try:
SELECT
sd.STAFF_ID || ' ' || s.STAFF_NAME AS "Staff Name",
d.DEPT_NAME AS "Department"
FROM STAFF_DEPT sd
INNER JOIN STAFF s ON sd.STAFF_ID = s.STAFF_ID
INNER JOIN DEPARTMENT d ON sd.DEPT_ID = d.DEPT_ID
GROUP BY sd.STAFF_ID || ' ' || s.STAFF_NAME, d.DEPT_NAME
HAVING COUNT (sd.STAFF_ID) > 1
Upvotes: 0