Oracle Query группировка с условием - PullRequest
0 голосов
/ 11 октября 2018

У меня есть результат запроса, подобный следующему:

DNAME           JOB       Total Empl    Average Sa
ACCOUNTING      CLERK           1       15600
ACCOUNTING      MANAGER         1       29400
ACCOUNTING      PRESIDENT       1       60000
ACCOUNTING      All Jobs        3       35000
RESEARCH        ANALYST         2       36000
RESEARCH        CLERK           2       11400
RESEARCH        MANAGER         1       35700
RESEARCH        All Jobs        5       26100
SALES           CLERK           1       11400
SALES           MANAGER         1       34200
SALES           SALESMAN        4       16800
SALES           All Jobs        6       18800
All Departments All Jobs        14      24878.5714

Можно ли измениться так, как это?

DNAME           JOB       Total Empl   Average Sa
ACCOUNTING      CLERK           1       15600
                MANAGER         1       29400
                PRESIDENT       1       60000
                All Jobs        3       35000
RESEARCH        ANALYST         2       36000
                CLERK           2       11400
                MANAGER         1       35700
                All Jobs        5       26100
SALES           CLERK           1       11400
                MANAGER         1       34200
                SALESMAN        4       16800
                All Jobs        6       18800
All Departments All Jobs        14      24878.5714

Мой существующий запрос:

SELECT 
DECODE(GROUPING(dname), 1, 'All Departments', dname) AS dname,
DECODE(GROUPING(job), 1, 'All Jobs', job) AS job,
COUNT(*) "Total Empl", AVG(sal) * 12 "Average Sal"
FROM emp, dept
WHERE dept.deptno = emp.deptno
GROUP BY ROLLUP (dname, job);

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Интерфейсные инструменты, такие как SQL * Plus, имеют специальные функции для выполнения именно того, что вам нужно.

В SQL * Plus вам просто нужно выполнить следующую команду перед тем, как запуститьзапрос КАК ЕСТЬ:

break on dname

Вы можете сделать то же самое в SQL Developer, если вы введете ту же команду BREAK на листе (и вы ее выполните), а затем выполните запрос "как скрипт"(кнопка" Run Script "или F5).

Если по какой-то причине вы должны сделать все это в одном операторе SQL, здесь есть один способ.Обратите внимание на третью строку в коде - это последний аргумент DECODE.Вы не видите double - это второй (вложенный) вызов DECODE.

SELECT 
DECODE(GROUPING(dname), 1, 'All Departments', 
  decode(job, min(job) over (partition by dname), dname) -- instead of just dname
) AS dname,
DECODE(GROUPING(job), 1, 'All Jobs', job) AS job,
COUNT(*) "Total Empl", AVG(sal) * 12 "Average Sal"
FROM scott.emp, scott.dept
WHERE dept.deptno = emp.deptno
 10  GROUP BY ROLLUP (dname, job);

DNAME           JOB       Total Empl Average Sal
--------------- --------- ---------- -----------
ACCOUNTING      CLERK              1       15600
                MANAGER            1       29400
                PRESIDENT          1       60000
                All Jobs           3       35000
RESEARCH        ANALYST            2       36000
                CLERK              2       11400
                MANAGER            1       35700
                All Jobs           5       26100
SALES           CLERK              1       11400
                MANAGER            1       34200
                SALESMAN           4       16800
                All Jobs           6       18800
All Departments All Jobs          14  24878.5714
0 голосов
/ 11 октября 2018

Один из подходов заключается в том, чтобы поместить текущий запрос в CTE, а затем генерировать названия отделов, только когда это первая запись в группе:

WITH cte AS (
    SELECT 
        DECODE(GROUPING(d.dname), 1, 'All Departments', d.dname) AS dname,
        DECODE(GROUPING(job), 1, 'All Jobs', job) AS job,
        COUNT(*) "Total Empl",
        AVG(sal) * 12 "Average Sal",
        ROW_NUMBER() OVER (PARTITION BY DECODE(GROUPING(d.dname), 1, 'All Departments', d.dname)
            ORDER BY DECODE(GROUPING(job), 1, 'All Jobs', job)) rn
    FROM emp e
    INNER JOIN dept d
        ON d.deptno = e.deptno
    GROUP BY ROLLUP (dname, job)
)

SELECT
    CASE WHEN rn = 1 THEN dname ELSE '' END AS dname,
    job,
    "Total Empl",
    "Average Sal"
FROM cte
ORDER BY
    dname,
    job;

Хотя это может соответствовать вашим ожиданиям, например,Проблемы с презентациями обычно лучше всего решать на уровне представления, например, что-то вроде PHP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...