Here is your original request:
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 performing aggregation on staff_id , but you have the staff_name and dept_name in your aggregation. You are looking for employees in several departments. You can get one line 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;
Note. I add list_agg() to select and s.staff_name to group by .
If you need one person / department for each row, 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;
Gordon linoff
source share