如何在 SQL 查询中对一列求和并显示在输出末尾的最后一行?

问题描述 投票:0回答:1
alter session set nls_date_format = 'dd/mm/yyyy';

ACCEPT input_year PROMPT 'Enter the year to check the quantity of each menu item ordered by customers (YYYY): ' 

col menu_id                format a10
col description            format a50
col total_sales_amount     format 9999.99

TTITLE CENTER 'Sales of Menu Item ordered by customers in ' &input_year ' compared with previous year' RIGHT 'Page:' SQL.PNO SKIP 2

WITH YearlyOrderData AS (
  SELECT
    m.MENU_ID,
    m.DESCRIPTION AS MENU_DESCRIPTION,
    TO_CHAR(o.ORDER_DATE, 'YYYY') AS ORDER_YEAR,
    SUM(oi.QUANTITY * oi.UNIT_PRICE) AS TOTAL_SALES_AMOUNT
  FROM
    orders o
    JOIN order_item oi ON o.ORDER_NO = oi.ORDER_NO
    JOIN menus m ON oi.MENU_ID = m.MENU_ID
  GROUP BY
    m.MENU_ID, m.DESCRIPTION, TO_CHAR(o.ORDER_DATE, 'YYYY')
),
DistinctMenuItems AS (
  SELECT DISTINCT MENU_ID, DESCRIPTION
  FROM menus
),
SELECT
  dmi.MENU_ID,
  dmi.DESCRIPTION AS MENU_DESCRIPTION,
  TO_CHAR(MAX(CASE WHEN yod.ORDER_YEAR = '&input_year' THEN yod.TOTAL_SALES_AMOUNT ELSE 0 END), '$999,999.99') AS "&input_year",
  TO_CHAR(MAX(CASE WHEN yod.ORDER_YEAR = TO_CHAR(TO_NUMBER('&input_year') - 1) THEN yod.TOTAL_SALES_AMOUNT ELSE 0 END), '$999,999.99') AS "Prev Year"
FROM
  DistinctMenuItems dmi
  LEFT JOIN YearlyOrderData yod ON dmi.MENU_ID = yod.MENU_ID
    AND (yod.ORDER_YEAR = '&input_year' OR yod.ORDER_YEAR = TO_CHAR(TO_NUMBER('&input_year') - 1))
GROUP BY
  dmi.MENU_ID, dmi.DESCRIPTION
ORDER BY
  dmi.MENU_ID;

以上是我的代码。输出将显示“&input_year”年和“上一年”中每个菜单项的total_sales_amount,如下所示:

                       Sales of Menu Item ordered by customers in 2023 compared with previous year       Page:         1

MENU_ID    MENU_DESCRIPTION                                                                 2023         Prev Year
---------- -------------------------------------------------------------------------------- ------------ ------------
BBSL       Blanched Bean Sprout Large                                                              $4.50       $12.00
BBSS       Blanched Bean Sprout Small                                                              $4.00        $7.00
BR1        Sourdough Potato Bread                                                                 $10.00        $9.00
BR2        Sourdough Loaf                                                                         $59.50         $.00
BR3        Sourdough Cheese Bread                                                                  $5.50        $9.00
C1C        CHAM O COLD                                                                            $16.00       $47.00
C1H        CHAM O HOT                                                                             $35.00       $21.00
C2C        CHAM COLD                                                                                $.00       $26.00
C2H        CHAM HOT                                                                                 $.00         $.00
C3C        CHAM C COLD                                                                            $36.50       $40.00
C3H        CHAM C HOT                                                                             $16.00         $.00
CF2        Chee Cheong Fun Set                                                                      $.00         $.00
CF3        Chee Cheong Fun Set + CharSiu                                                          $37.50      $152.00
DHC        Drumstick Hainan Chicken Rice                                                            $.00         $.00
G01        Chicken and Pork Horfun                                                                $11.90       $59.50
G02        Old Style Ipoh Gai Si Horfun                                                          $111.80      $114.80
GP1        Special Horfun                                                                        $150.00       $72.00
HC0        Hainan Chicken Rice                                                                      $.00       $13.00
HHC        one half Hainan Chicken                                                                  $.00         $.00
K1C        KOPI O COLD                                                                              $.00       $20.00
K1H        KOPI O HOT                                                                             $28.00       $31.00
K2C        KOPI COLD                                                                               $6.50       $36.00
K2H        KOPI HOT                                                                               $16.00        $4.30
K3C        KOPI C COLD                                                                              $.00         $.00
K3H        KOPI C HOT                                                                             $20.00        $3.00
K4C        KOPI SARAWAK COLD                                                                      $27.50       $22.50
K4H        KOPI SARAWAK HOT                                                                         $.00       $46.00
KB1        Black Kampua (With Kampua Daoyu)                                                       $25.00         $.00
KB2        Black Kampua with Gyoza                                                                  $.00       $90.00
KB3        Black Kampua withHainan Chicken                                                        $70.40       $83.50

它们是两列。我想显示这两列中每一列的总计。有人可以帮我解决这个问题吗?我应该使用 COMPUTE 语法吗?

我尝试使用 COMPUTE 但不知何故它不起作用。也许我写错了。

sql oracle sqlplus
1个回答
0
投票

您可以使用如下所示的 MODEL 子句。首先是一些示例数据和要使用的 CTE:

WITH 
    orders AS
        (   Select 20220001 "ORDER_NO", To_Date('01.09.2022', 'dd.mm.yyyy') "ORDER_DATE" From Dual Union All
            Select 20220002 "ORDER_NO", To_Date('01.09.2022', 'dd.mm.yyyy') "ORDER_DATE" From Dual Union All
            Select 20220003 "ORDER_NO", To_Date('01.09.2022', 'dd.mm.yyyy') "ORDER_DATE" From Dual Union All
            Select 20230001 "ORDER_NO", To_Date('01.09.2023', 'dd.mm.yyyy') "ORDER_DATE" From Dual Union All
            Select 20220002 "ORDER_NO", To_Date('01.09.2023', 'dd.mm.yyyy') "ORDER_DATE" From Dual
        ),
    order_item AS
        (   Select 20220001 "ORDER_NO", 101 "UNIT_ID", 1101 "MENU_ID", 5 "QUANTITY", 12 "UNIT_PRICE" From Dual Union All
            Select 20220002 "ORDER_NO", 102 "UNIT_ID", 1102 "MENU_ID", 4 "QUANTITY", 12 "UNIT_PRICE" From Dual Union All
            Select 20220003 "ORDER_NO", 103 "UNIT_ID", 1103 "MENU_ID", 3 "QUANTITY", 12 "UNIT_PRICE" From Dual Union All
            Select 20230001 "ORDER_NO", 101 "UNIT_ID", 1101 "MENU_ID", 2 "QUANTITY", 10 "UNIT_PRICE" From Dual Union All
            Select 20230002 "ORDER_NO", 102 "UNIT_ID", 1102 "MENU_ID", 1 "QUANTITY", 10 "UNIT_PRICE" From Dual 
        ),
    menus AS
        (   Select 1101 "MENU_ID", 'Description of 101' "DESCRIPTION" From Dual Union All
            Select 1102 "MENU_ID", 'Description of 102' "DESCRIPTION" From Dual Union All
            Select 1103 "MENU_ID", 'Description of 103' "DESCRIPTION" From Dual 
        ),
    YearlyOrderData AS
        (
            SELECT  m.MENU_ID,
              m.DESCRIPTION AS MENU_DESCRIPTION,
              TO_CHAR(o.ORDER_DATE, 'YYYY') AS ORDER_YEAR,
              SUM(oi.QUANTITY * oi.UNIT_PRICE) AS TOTAL_SALES_AMOUNT
            FROM    orders o
            JOIN    order_item oi ON o.ORDER_NO = oi.ORDER_NO
            JOIN    menus m ON oi.MENU_ID = m.MENU_ID
            GROUP BY    m.MENU_ID, m.DESCRIPTION, TO_CHAR(o.ORDER_DATE, 'YYYY')
        ),
    DistinctMenuItems AS 
        (
            SELECT DISTINCT MENU_ID, DESCRIPTION
            FROM menus
        )

现在对主 SQL 进行建模(将金额类型更改为用于求和的数字)

Select *
From    ( SELECT        dmi.MENU_ID,
                    dmi.DESCRIPTION AS MENU_DESCRIPTION,
                    MAX(CASE WHEN yod.ORDER_YEAR = '&input_year' THEN yod.TOTAL_SALES_AMOUNT ELSE 0 END) AS "ACT_YEAR",
                    MAX(CASE WHEN yod.ORDER_YEAR = TO_CHAR(TO_NUMBER('&input_year') - 1) THEN yod.TOTAL_SALES_AMOUNT ELSE 0 END) AS "PREV_YEAR"
          FROM      DistinctMenuItems dmi
          LEFT JOIN     YearlyOrderData yod ON dmi.MENU_ID = yod.MENU_ID AND 
                      (yod.ORDER_YEAR = '&input_year' OR yod.ORDER_YEAR = TO_CHAR(TO_NUMBER('&input_year') - 1))
          GROUP BY  dmi.MENU_ID, dmi.DESCRIPTION
          ORDER BY  dmi.MENU_ID
        )
        MODEL     Dimension By  (MENU_ID)
                  Measures      (MENU_DESCRIPTION, ACT_YEAR, PREV_YEAR)
        RULES   ( MENU_DESCRIPTION[Null] = 'T o t a l :',
                  ACT_YEAR[Null] = Sum(ACT_YEAR)[MENU_ID Is Not Null],
                  PREV_YEAR[Null] = Sum(PREV_YEAR)[MENU_ID Is Not Null]
                )
--  R e s u l t :
--     MENU_ID MENU_DESCRIPTION     ACT_YEAR  PREV_YEAR
--  ---------- ------------------ ---------- ----------
--        1101 Description of 101         20         60
--        1102 Description of 102         48         48
--        1103 Description of 103          0         36
--             T o t a l :                68        144
© www.soinside.com 2019 - 2024. All rights reserved.