簡體   English   中英

SQL 查詢按月分組並顯示單個月總和記錄

[英]SQL Query to group by month and display individual month sum for a record

我正在嘗試將具有特定描述的產品代碼匯總為多年來一個月內銷售的總產品。

在此處輸入圖像描述

使用的兩個表是:

CREATE TABLE product (
    prod_code          NUMBER(3) NOT NULL,
    prod_description   VARCHAR2(75) NOT NULL,
    prod_points        NUMBER(2) NOT NULL
);

CREATE TABLE product_sale (
    sale_no         NUMBER(8) NOT NULL,
    sale_datetime   DATE NOT NULL,
    sale_location   VARCHAR2(100) NOT NULL,
    prod_code       NUMBER(3) NOT NULL,
    officer_id     NUMBER(8) NOT NULL,
);

日期格式為“DD-MON-YYYY HH12:MI PM”。

到目前為止,我能夠制定這個:

select  
d.prod_description, 
extract(month from sale_datetime) as mon, 
count(d.prod_code) as count
from product d 
 join product_sale o on d.prod_code = o.prod_code
group by d.prod_description, extract(month from sale_datetime);
order by d.prod_code;

如何將計數分隔為不同的月份列並在單獨的列中獲取計數總和?

我只會使用條件聚合:

select d.prod_description, count(*) as total,
       sum(case when extract(month from sale_datetime) = 1 then 1 else 0 end) as jan, 
       sum(case when extract(month from sale_datetime) = 2 then 1 else 0 end) as feb, 
       . . .
from product d join
     product_sale o 
     on d.prod_code = o.prod_code
group by d.prod_code, d.prod_description
order by d.prod_code;

請注意,對於排序, prod_code需要在group by -- 或者您需要使用聚合 function 例如order by min(d.prod_code)

如果您想要單獨的總計行,請使用grouping sets

group by grouping sets ( (d.prod_code, d.prod_description), () )

因此,JAN 列應包含每年一月的計數。

我將假設除了水平總和之外,您還需要垂直總和。

首先需要在不同級別進行聚合,然后PIVOT將不同行的數據獲取到同一行的不同列中。

為了在不同級別進行聚合,Oracle 提供了GROUP BY擴展,例如CUBE

select prod_code, prod_description,
  nvl(extract(month from sale_datetime),0) mon,
  count(*) cnt
from product join product_sale using(prod_code)
group by cube((prod_code, prod_description), extract(month from sale_datetime))

現在你可以 pivot:

select * from (
  select prod_code, prod_description,
    nvl(extract(month from sale_datetime),0) mon,
    count(*) cnt
  from product join product_sale using(prod_code)
  group by cube((prod_code, prod_description), extract(month from sale_datetime))
)
pivot(max(cnt) for mon in(
  0 sum,1 jan,2 feb,3 mar,4 apr,5 may,6 jun,7 jul,8 aug,9 sep,10 oct,11 nov,12 dec
))
order by prod_description;

PROD_CODE   PROD_DESCRIPTION   SUM    JAN   FEB   MAR   APR   MAY   JUN   JUL   AUG   SEP   OCT   NOV   DEC 
        1   1                  516     61    57    62    60    62    30    31    31    30    31    30    31 
        2   2                  516     61    57    62    60    62    30    31    31    30    31    30    31 
        3   3                  516     61    57    62    60    62    30    31    31    30    31    30    31 
        4   4                  516     61    57    62    60    62    30    31    31    30    31    30    31 
        5   5                  516     61    57    62    60    62    30    31    31    30    31    30    31 
        6   6                  516     61    57    62    60    62    30    31    31    30    31    30    31 
        7   7                  516     61    57    62    60    62    30    31    31    30    31    30    31 
        8   8                  516     61    57    62    60    62    30    31    31    30    31    30    31 
        9   9                  516     61    57    62    60    62    30    31    31    30    31    30    31 
                              4644    549   513   558   540   558   270   279   279   270   279   270   279 

這是一個簡化的解決方案,例如我沒有 label 底部的垂直總和行。 有關此技術的完整解決方案和說明,請參閱https://stewashton.wordpress.com/2016/07/18/spreadsheet-like-totals-and-subtotals/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM