Oracle вложенный выбор с определенными строками - PullRequest
0 голосов
/ 01 мая 2020

Мой запрос выглядит следующим образом:

SELECT
    nvl(dd,'TOTAL') "Subject",
    SUM(cnt) "Count,
    SUM(pct) AS "%"
FROM
    (
SELECT
    dd,
    COUNT(1) cnt,
    round(RATIO_TO_REPORT(COUNT(1) ) OVER() * 100,2) AS pct
FROM
    student p,
    student_subject a
WHERE
    p.sId = a.sId
    AND student_type IN (
        '1',
        '2'
    )
    AND dd IN (
        'MATH',
        'SCIENCE',
        'HISTORY'
    )
    GROUP BY
    dd
ORDER BY
    1
)
GROUP BY
    ROLLUP(dd)
ORDER BY
    1;

Мой вывод должен выглядеть следующим образом:

Subject Count       %
MATH    33          23.2%
SCIENCE 24          11.46%
HISTORY 56          44.778%
TOTAL   113         85.4.2%

Если у конкретного субъекта нет данных, он все равно должен предоставить строке 0 значений как показано ниже

Subject Count       %
MATH    33          23.20%
SCIENCE 0           0.00%
HISTORY 56          44.77%
TOTAL   113         85.42%

То, что я получаю, теперь справа, без строки НАУКИ, которая не нужна,

Subject Count       %
MATH    33          23.20%
HISTORY 56          44.77%
TOTAL   113         85.42%

Что я сделал, я удалил предложение dd IN "И dd IN («МАТЕМАТИКА», «НАУКА», «ИСТОРИЯ») «Однако я не могу добраться до другого внутреннего выбора, чтобы выбрать 3 предмета.

Ответы [ 3 ]

1 голос
/ 01 мая 2020

Если я правильно понимаю модель данных, когда студент не зачислен на предмет, запись для предмета не будет существовать в таблице student_subject, что означает, что отсутствующий предмет также отсутствует в таблице дефицита. Следовательно, технически невозможно объединить эти две таблицы и сообщить о значении столбца, которого нет ни в одной из них. Теперь, чтобы решить эту проблему, я использую предложение WITH, чтобы создать другую таблицу для хранения всех нужных объектов и выполнить внешнее объединение с полученным набором результатов.

Я проверил это, и оно работает отлично. Полное решение (Oracle 18 c) с таблицей и запросом можно найти в DBFIDDLE URL https://dbfiddle.uk/?rdbms=oracle_18&fiddle=df73453d7fa4e0478e74fa509b20a411.

  WITH some_data AS ( 
       SELECT 'MATH' AS subj
       FROM dual
       UNION ALL 
       SELECT 'SCIENCE' AS subj
       FROM dual
       UNION ALL
       SELECT 'HISTORY' AS subj
       FROM dual
    )
    SELECT
        nvl(subj,'TOTAL') "Subject",
        nvl(SUM(cnt),0) "Count",
        nvl(SUM(pct),0) AS "%"
    FROM
    (SELECT
        dd,
        COUNT(1) cnt,
        round(RATIO_TO_REPORT(COUNT(1) ) OVER() * 100,2) AS pct
    FROM
        student p,
        student_subject a
    WHERE
        p.sId = a.sId
        AND student_type IN (
            '1',
            '2'
        )
        AND dd IN (
            'MATH',
            'SCIENCE',
            'HISTORY'
        )
        GROUP BY
        dd
    ORDER BY
        1
    ) tab, some_data
    where tab.dd(+) = some_data.subj
    GROUP BY
        ROLLUP(subj)
    ORDER BY
        1;
0 голосов
/ 01 мая 2020

Вам необходимо использовать список таблиц как inner view и использовать left join следующим образом:

SELECT NVL(DD, 'TOTAL') "Subject",
       SUM(CNT) "Count",
       SUM(PCT) AS "%"
FROM (
    SELECT DD,
           COUNT(1) CNT,
           ROUND(RATIO_TO_REPORT(COUNT(1)) OVER() * 100, 2) AS PCT
    FROM (
        SELECT 'MATH' AS SUB FROM DUAL UNION ALL
        SELECT 'SCIENCE' AS SUB FROM DUAL UNION ALL
        SELECT 'HISTORY' AS SUB FROM DUAL
    ) SUBJECTS
    LEFT JOIN STUDENT_SUBJECT A
    ON SUBJECTS.SUB = A.DD
    LEFT JOIN STUDENT P
    ON P.SID = A.SID
    WHERE STUDENT_TYPE IN (
        '1','2'
    )
    GROUP BY DD
    ORDER BY 1
)
GROUP BY ROLLUP(DD)
ORDER BY 1;
0 голосов
/ 01 мая 2020


Привет,
Вы должны использовать оператор case, чтобы сделать его 0. Если какой-либо из субъектов является нулевым, то по умолчанию его значение равно 0. Дайте мне знать, если вам требуется запрос. Предлагаю логи c, чтобы вы могли попробовать сами. Если у вас возникнут вопросы, дайте мне знать.

Спасибо

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