Как показать общую прибыль за каждый месяц, показать ноль, если в этом месяце нет записи в оракуле - PullRequest
2 голосов
/ 03 ноября 2019

Я создаю отчет, показывающий общую прибыль каждого месяца в 2018 году, и показываю NIL, когда нет прибыли, полученной в определенные месяцы

полученная прибыль = 0,1 * Total_payment. Прибыль зарабатывают, когда услуга завершена, столбец «Total_payment» берется из таблицы «БРОНИРОВАНИЕ», мне нужно присоединиться к «БРОНИРОВАНИЮ и СЕРВИСУ», чтобы получать общую прибыль за каждый месяц, «Booking_num» является ключом для объединения «БРОНИРОВАНИЯ и СЕРВИСА»,Actual_end - это дата окончания услуги

Теперь проблема в том, что в январе, феве и авг нет прибыли. есть ли в любом случае показывать NIL в столбце прибыли ЗА ЭТОТ ТРИ МЕСЯЦА?

SELECT EXTRACT(MONTH FROM Actual_end) AS MONTH,SUM(Total_payment *0.1) AS PROFIT
FROM SERVICE,BOOKING
WHERE SERVICE.Booking_num = BOOKING.Booking_num
AND EXTRACT(YEAR FROM Actual_end) = 2018
GROUP BY EXTRACT(MONTH FROM Actual_end);

Это код показа прибыли за 9 месяцев без jan, feb и aug

MONTH  PROFIT
3      88.4
4      146.1
5      112.6
6      108.3
7      102.6
9      130.3
10     72.6
12     124.9

Iожидайте, что выходной сигнал будет

MONTH    PROFIT
1        NIL
2        NIL
3        88.4
4        146.1 
5        112.6
6        108.3
7        102.6
8        NIL
9        130.3
10       72.6
11       124.9
12       25.2

как мне его изменить, я также попытался

WITH CALENDAR AS(
SELECT TO_CHAR(add_months(date '2018-01-01',ROWNUM -1),'MM') AS MONTH
FROM DUAL
CONNECT BY LEVEL <=12)
SELECT CALENDER.MONTH, NVL(SUM(Total_payment*0.1),null) AS PROFIT
FROM BOOKING,SERVICE,CALENDER
WHERE BOOKING.Booking_num = SERVICE.Booking_num
AND CALENDER.MONTH = EXTRACT(MONTH FROM Actual_end(+))
AND EXTRACT(MONTH FROM Actual_end) = 2018
GROUP BY CALENDER.MONTH

ВЫХОД: ВЫБОР НЕ СТРОИТ

Ответы [ 2 ]

2 голосов
/ 03 ноября 2019

Вам нужно и внешнее соединение (левое или правое). Кстати, избавьтесь от устаревшего объединения таблиц через запятую, скорее используйте явное объединение.

Добавьте RIGHT JOIN (SELECT LEVEL AS MNT FROM DUAL CONNECT BY LEVEL <= 12 ) MNT к вашему запросу, если имеет значение возврат одного определенного года с целыми месяцами:

SELECT MNT AS MONTH,NVL(TO_CHAR(SUM(Total_payment *0.1)),'NIL') AS PROFIT
  FROM SERVICE S
  JOIN BOOKING B
    ON S.Booking_num = B.Booking_num
 RIGHT JOIN (SELECT LEVEL AS MNT 
               FROM DUAL 
             CONNECT BY LEVEL <= 12 ) MNT
         ON MNT.MNT = EXTRACT(MONTH FROM Actual_end) 
           AND EXTRACT(YEAR FROM Actual_end)=2018                     
GROUP BY MNT
ORDER BY MONTH;

Демо

0 голосов
/ 03 ноября 2019

В этом случае вам нужен список всех месяцев:

with months as (
      select 1 as month from dual union all
      select 2 as month from dual union all
      select 3 as month from dual union all
      select 4 as month from dual union all
      select 5 as month from dual union all
      select 6 as month from dual union all
      select 7 as month from dual union all
      select 8 as month from dual union all
      select 9 as month from dual union all
      select 10 as month from dual union all
      select 11 as month from dual union all
      select 12 as month from dual
     )
select m.month, sum(s.total_payment * 0.1) as profit
from months m left join
     booking b
     on extract(month from b.actual_end) = m.month and
        b.actual_end >= date '2018-01-01' and
        b.actual_end < date '2019-01-01' left join
     service s join
     on s.booking_num = b.booking_num 
group by m.month;

Примечание:

  • Предполагается, что actual_end находится в booking и total_paymentнаходится в service. Запрос будет немного другим, если это предположение неверно.
  • Никогда не используйте запятые в предложении FROM.
  • Этот запрос должен использовать LEFT JOIN. В первой таблице есть все нужные вам строки.
  • Фильтры в последующих таблицах идут в предложении on, а не в предложении where.
  • Обратите внимание на использование констант даты. Такие сравнения обычно облегчают движку оптимизацию запроса (обычно с использованием индексов).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...