2016-11-02 3 views
1

У меня есть простая база данных для имитации проката фильмов. У меня есть следующие 3 запросов на выборку, которые работают прекрасно сами по себе:Объединить 3 колонки в одну таблицу

  1. Вычислить все доходы сделаны из цен на аренду:

    SELECT SUM(PRICE) AS RENTAL_REVENUE 
        FROM RENTAL 
    

    выход:

    +----------------+ 
        | RENTAL_REVENUE | 
        +----------------+ 
        |  39.92  | 
        +----------------+ 
    
  2. Вычислить все выручка от уплаченных просроченных сборов:

    SELECT SUM(NULLIF(LATEFEE, 0)) AS PAID_LATE_FEES 
        FROM RENTAL 
        WHERE RETURNED = 1 
    

    выход:

    +----------------+ 
        | PAID_LATE_FEES | 
        +----------------+ 
        |  2.99  | 
        +----------------+ 
    
  3. Вычислить сумму всех еще неоплаченных штрафов за просрочку платежа:

    SELECT SUM(NULLIF(LATEFEE, 0)) AS OUTSTANDING_LATE_FEES 
        FROM RENTAL 
        WHERE RETURNED = 0 
    

    выход:

    +-----------------------+ 
        | OUTSTANDING_LATE_FEES | 
        +-----------------------+ 
        |   5.98   | 
        +-----------------------+ 
    

Я хотел бы объединить результаты этих 3 запроса в таблицу с тремя столбцами, например:

+----------------+----------------+-----------------------+ 
| RENTAL_REVENUE | PAID_LATE_FEES | OUTSTANDING_LATE_FEES | 
+----------------+----------------+-----------------------+ 
|  39.92  |  2.99  |   5.98   | 
+----------------+----------------+-----------------------+ 

Мне удалось достичь этого со следующим запросом, но глупость 1 = 1 подсказывает мне, что может быть лучший способ.

SELECT rental_revenue + paid_late_fees + outstanding_late_fees AS TOTAL_REVENUE, 
     rental_revenue, 
     paid_late_fees, 
     outstanding_late_fees 
FROM (SELECT SUM(price) AS RENTAL_REVENUE 
     FROM rental) 
     inner join (SELECT SUM(Nullif(latefee, 0)) AS PAID_LATE_FEES 
        FROM rental 
        WHERE returned = 1) 
       ON 1 = 1 
     inner join (SELECT SUM(Nullif(latefee, 0)) AS OUTSTANDING_LATE_FEES 
        FROM rental 
        WHERE returned = 0) 
       ON 1 = 1; 

Есть ли лучший способ?

ответ

5

Вы можете выбрать все записи и построить фильтр внутри SUM с помощью CASE-WHEN или DECODE:

SELECT SUM(price) AS rental_revenue, 
     SUM(CASE 
      WHEN returned = 1 AND latefee <> 0 THEN latefee 
      ELSE 0 
      END) AS paid_late_fees, 
     SUM(CASE 
      WHEN returned = 0 AND latefee <> 0 THEN latefee 
      ELSE 0 
      END) AS outstanding_late_fees    
FROM rental 
+0

Почему вы убедитесь, что поздно плата не 0? Разве это не повлияло бы на сумму? – Alexander

+0

Вы правы, но OP проверил это. Я думал, что если бы я тоже это проверил, это было бы менее смутно для него. – pablomatico

+0

Я ОП. Лол, я не заметил, что на самом деле туда попал, он, должно быть, пробрался от какого-то более раннего трюка, который я делал :) – Alexander

2

Вы можете просто использовать case выражение или decode() функции

select sum(price) as return_revenue 
    , sum(case 
      when returned = 1 
      then latefee 
      end) as paid_late_fees 
    , sum(case 
      when returned = 0 
      then latefee 
      end) as outstanding_late_fees   
    from rental