Reputation: 65
SELECT e.name
from emp e, departm d, salery s
WHERE e.dep=d.depid
AND s.emp= e.empid
AND s.sal > (SELECT round(avg(s.sal)) as AVGSAL
from emp e, departm d, salery s
WHERE e.dep=d.depid AND s.emp= e.empid
GROUP BY d.depid
);
MY Tables are:
emp (empid, name, dep)
departm (depid, name, headdep)
salery (emp, cost, sal, fdate)
I have some foreign keys:
departm: FOREIGN KEY (headdep) REFERENCES departm(depid)
emp: FOREIGN KEY(dep) REFERENCES departm(depid)
salery: FOREIGN KEY(emp) REFERENCES emp(empid)
I want to print a list of all employees which earn more money than the average of theyr department but when i run this query i have an error: single-row subquery returns more than one row
Can anyone help me? What's the problem with my query? Finally I want to create a procedure, but first of all i have to write the query.
Thank you guys...
Upvotes: 0
Views: 126
Reputation: 1269583
Analytic functions are the way to go on this query, but your version has several problems. You would see these problems much more readily if you used proper join syntax. You seem to be learning SQL, so just remember one simple rule: NEVER use commas in from
clauses.
Apart from the syntax problem, you have a problem with your correlated subquery. Here is a version that should work:
SELECT e.vollername
from emp e join
salery s
on s.emp= e.empid
WHERE s.sal > (select round(avg(s2.sal)) as AVGSAL
from emp e2 join
salery s2
on s2.emp= e2.empid
where e2.dep = e.depid
);
Note the removal of the departm
table from both the inner and the outer queries. In the outer one, it was merely superfluous. In the inner one, it prevented the query from producing the correct results because it removed the correlation.
Upvotes: 2
Reputation: 30765
This is somewhat easier with analytic functions (I also removed the join with departm
, since it is not needed):
SELECT e.vollername
FROM (
SELECT
e.vollername,
s.sal,
round(avg(s.sal) over (partition by e.dep)) as avg_dep_sal
FROM
emp e
JOIN salery s ON e.empid = s.emp
)
where sal > avg_dep_sal
Upvotes: 1