简体   繁体   中英

“Double Group By” in Oracle SQL?

As I was learning SQL statements I encountered one example (regarding the demo SCOTT database), I have no idea how to solve.

In which department(s) are all salgrades present?

My most promising approach is to group all salgrades and departments in the joined tables emp , dept and salgrade :

SELECT s.grade AS "Salgrade",
       d.dname AS "Department ID"
FROM emp e INNER JOIN dept d ON(e.deptno = d.deptno)
     INNER JOIN salgrade s ON(e.sal BETWEEN s.losal AND s.hisal)
GROUP BY d.dname, s.grade

Executing this gives me the following results:

结果

If I could group this another time by department, COUNT(*) could give me the number of different salgrades per department . Then I could compare this number (with HAVING ) to the following subselect:

(SELECT COUNT(*)
 FROM salgrade)

Is there any possibility to group a table which already contains GROUP BY ? Is there another (better) approach I could use?


I am using an apex-oracle-server with "Application Express 4.2.4.00.07"

Minor change from your version, by removing the grouping inside, and this version, first generates, salgrade and department of all employees, and then doing a grouping outside, counting distinct salary grades.

SELECT Department_ID
FROM
(
 SELECT s.grade AS Salgrade,
        d.dname AS Department_ID
 FROM emp e 
  INNER JOIN dept d ON(e.deptno = d.deptno)
  INNER JOIN salgrade s ON(e.sal BETWEEN s.losal AND s.hisal)
 )
GROUP BY Department_ID
HAVING COUNT(distinct Salgrade) = ( SELECT count(1) FROM salgrade);

I found an even easier solution now:

SELECT d.dname
FROM emp e  INNER JOIN dept d ON(e.deptno = d.deptno)
            INNER JOIN salgrade s ON(e.sal BETWEEN s.losal AND s.hisal)
GROUP BY d.dname
HAVING COUNT(DISTINCT s.grade) = (SELECT COUNT(*) FROM salgrade);

Simple way would be - if performance is not a problem.

SELECT
COUNT(DISTINCT [Salgrade]) AS [COUNT]
,[Department ID]
FROM (SELECT s.grade AS "Salgrade",
       d.dname AS "Department ID"
FROM emp e INNER JOIN dept d ON(e.deptno = d.deptno)
     INNER JOIN salgrade s ON(e.sal BETWEEN s.losal AND s.hisal)
GROUP BY d.dname, s.grade) DEPT_SALE
GROUP BY [Department ID]

There could be better solutions though if we know more of your base tables - emp & salegrade

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM