在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
前言节前公司业务方需要做一個統計報表,这个报表用于统计当月估计几个明星品的销售情况,而我们的数据是按行存储的就是 报表首先,業務需要的報表長這樣子的,看起來似乎還OK哈~ 接下來我先給出我的測試脚本(均測試&無bug)~ 表结构 drop table if EXISTS report1 ; CREATE TABLE "report1" ( "id" numeric(22) NOT NULL, "date" date NOT NULL, "product" varchar(100), "channel" varchar(100), "amount" numeric(20,4) ); 表注释
表数据 INSERT INTO "report1"("id", "date", "product", "channel", "amount") VALUES ('2105051726328010100000', '2021-05-04', '产品1', '京东', '8899.0000'); INSERT INTO "report1"("id", "date", "product", "channel", "amount") VALUES ('2105051726328010100001', '2021-05-04', '产品2', '京东', '99.0000'); INSERT INTO "report1"("id", "date", "product", "channel", "amount") VALUES ('2105051727068010100010', '2021-05-04', '产品1', '天猫', '230.0000'); INSERT INTO "report1"("id", "date", "product", "channel", "amount") VALUES ('2105051727068010100011', '2021-05-04', '产品2', '天猫', '9.9000'); INSERT INTO "report1"("id", "date", "product", "channel", "amount") VALUES ('2105051727068010100011', '2021-05-04', '产品3', '线下门店', '10.1000'); INSERT INTO "report1"("id", "date", "product", "channel", "amount") VALUES ('2105051727068010100000', '2021-05-04', '产品1', '其它', '10'); INSERT INTO "report1"("id", "date", "product", "channel", "amount") VALUES ('2105051727068010100099', '2021-05-04', '产品2', '其它', '20000'); INSERT INTO "report1"("id", "date", "product", "channel", "amount") VALUES ('2105051727068010100033', '2021-05-01', '产品1', '其它', '20000'); INSERT INTO "report1"("id", "date", "product", "channel", "amount") VALUES ('2105051727068010100044', '2021-05-01', '产品3', '线下门店', '12345'); 思考如果你看到這裏請稍稍思考下,一開篇我説過我們的數據是按
一部分是前一日產品銷售明細
一部分是前一日的數據 最後一部分則是所有渠道的產品合計、日合計、月合計 好了,問題來了,如何做呢,我是這麽想的:首先要很清楚的是你的sql大致分兩大部分(兩個子查詢) 一部分是前一日的數據另一部分則是月份匯總數據 最後需要將兩部分數據做聯表查詢,這樣太贊了,似乎完成了報表的80%,至於最後一行的求總,這裏先賣個關子哈~ 第一部分數據(前一日的數據) 我想我們立馬能做的第一部分sql恐怕就是行專列吧(似乎這是最容易實現的😄) select channel, sum(case product when '产品1' then amount end) as c1, sum(case product when '产品2' then amount end) as c2, sum(case product when '产品3' then amount end) as c3 from report1 group by channel ; sql似乎沒什麽問題,但是我們少了一列,對那就是 select channel, day_sum, sum(case product when '产品1' then amount end) as c1, sum(case product when '产品2' then amount end) as c2, sum(case product when '产品3' then amount end) as c3 from ( select *,sum(amount) over (partition by channel) as day_sum from report1 where date=to_date('2021-05-04','yyyy-MM-dd') ) as t1 group by t1.channel ,t1.day_sum; 哈哈,上圖的
想想是不是很容易😂,接下來我們看看第二部分數據怎麽獲取~ 第二部分數據(月份匯總數據) 月份匯總的數據看似簡單的可怕,如果您熟練掌握postgresql中的日期處理的話估計分分鐘就能搞定,這裏就不耍大刀了,直接放出sql,哈哈哈😄 select channel,sum(amount) as month_sum from report1 where date>=date(date_trunc('month',to_date('2021-05-04','yyyy-MM-dd'))) and date < date(date_trunc('month',to_date('2021-05-04','yyyy-MM-dd')) + '1 month') group by channel 報表數據最終求解 現在,我們將求解的兩部分數據按渠道 這個是sql select ttt.channel, sum(ttt.day_sum) as day_sum, sum(ttt.month_sum) as month_sum, sum(ttt.c1) as c1, sum(ttt.c2) as c2, sum(ttt.c3) as c3 from ( select tt1.*,tt2.month_sum from ( select channel, day_sum, sum(case product when '产品1' then amount end) as c1, sum(case product when '产品2' then amount end) as c2, sum(case product when '产品3' then amount end) as c3 from ( select *,sum(amount) over (partition by channel) as day_sum from report1 where date=to_date('2021-05-04','yyyy-MM-dd') ) as t1 group by t1.channel ,t1.day_sum ) as tt1 left join ( select channel,sum(amount) as month_sum from report1 where date>=date(date_trunc('month',to_date('2021-05-04','yyyy-MM-dd'))) and date < date(date_trunc('month',to_date('2021-05-04','yyyy-MM-dd')) + '1 month') group by channel ) as tt2 on tt1.channel = tt2.channel ) ttt GROUP BY ttt.channel order by channel asc 看,匯總的數據已經有了,已經可以算作是最終結果了(如果你需要報表系統來計算匯總行數據的話),當然 ,我們的報表系統過於繁瑣(不是不能做,而是太麻煩),需要你將做好的菜喂給它吃,這時,該怎麽辦呢。。。,哈哈哈 我們似乎忘記了很久不用的 select ttt.channel, sum(ttt.day_sum) as day_sum, sum(ttt.month_sum) as month_sum, sum(ttt.c1) as c1, sum(ttt.c2) as c2, sum(ttt.c3) as c3 from ( select tt1.*,tt2.month_sum from ( select channel, day_sum, sum(case product when '产品1' then amount end) as c1, sum(case product when '产品2' then amount end) as c2, sum(case product when '产品3' then amount end) as c3 from ( select *,sum(amount) over (partition by channel) as day_sum from report1 where date=to_date('2021-05-04','yyyy-MM-dd') ) as t1 group by t1.channel ,t1.day_sum ) as tt1 left join ( select channel,sum(amount) as month_sum from report1 where date>=date(date_trunc('month',to_date('2021-05-04','yyyy-MM-dd'))) and date < date(date_trunc('month',to_date('2021-05-04','yyyy-MM-dd')) + '1 month') group by channel ) as tt2 on tt1.channel = tt2.channel ) ttt group by rollup(ttt.channel) order by channel asc 數是對的,意味著我們成功了~😂 總結如果您肯下功夫學, 下章,我將講一講如何實現通過sql實現前端合并單元格的效果,是不是很神奇(我保證你全網搜不到), 希望不翻車,哈哈哈~ 到此这篇关于postgresql高级应用之行转列&汇总求和的实现思路的文章就介绍到这了,更多相关postgresql行转列汇总求和内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! |
请发表评论