postgresql高級(jí)應(yīng)用之合并單元格的思路詳解
1.寫在前面✍
繼上一篇postgresql高級(jí)應(yīng)用之行轉(zhuǎn)列&匯總求和之后想更進(jìn)一步做點(diǎn)兒復(fù)雜的(圖表暫且不論哈😂),當(dāng)然作為報(bào)表,出現(xiàn)最多的無(wú)非就是合并單元格了,是的,我已經(jīng)迫不及待啦😎~
2.思考
首先,我們的腦海中應(yīng)該有一個(gè)對(duì)前端table
有一個(gè)大致的了解, 當(dāng)然這對(duì)非前端的同學(xué)十分的不友好,如果您嘗試閲讀以下內(nèi)容存在困難的話(前端html
、javascript
) 可就此打住哈。。。
enn...,讓我先稍稍解釋下前端 html
的表格格式吧😀
2.1 前端html
->table
基本結(jié)構(gòu)
先給出一個(gè)十分base的html demo.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>demo</title> </head> <body> <!-- 這裏定義了兩個(gè)屬性 border:定義表格邊框 cellpadding:定義單元格大小 --> <table border="3" cellpadding="8"> <thead> <tr> <th>表頭1</th><th>表頭2</th><th>表頭3</th> </tr> </thead> <tbody> <tr> <td>第一行第1個(gè)</td><td>第一行第2個(gè)</td><td>第一行第3個(gè)</td> </tr> <tr> <!-- 使用colspan屬性進(jìn)行橫向合并,橫向被合并的單元格位置需要騰出來(lái) --> <!-- 以下橫向合并兩個(gè)單元格,所以第二個(gè)td標(biāo)簽就不要寫了,否則會(huì)溢出哦~ --> <td colspan="2">橫向合并了兩個(gè)單元格</td><td>第二行第3個(gè)</td> </tr> <tr> <td>第三行第1個(gè)</td><td>第三行第2個(gè)</td><td>第三行第3個(gè)</td> </tr> <tr> <!-- 使用rowspan屬性進(jìn)行縱向合并,縱向合并的(跨越的)單元格位置需要騰出來(lái) --> <!-- 以下縱向合并三個(gè)個(gè)單元格(在本行最後一個(gè)標(biāo)簽),所以下兩行的最後兩個(gè)td標(biāo)簽就不要寫啦~,否則同樣會(huì)溢出哦~ --> <td>第四行第1個(gè)</td><td>第四行第2個(gè)</td><td rowspan="3">縱向合并了三個(gè)單元格</td> </tr> <tr> <td>第五行第1個(gè)</td><td>第五行第2個(gè)</td> </tr> <tr> <td>第六行第1個(gè)</td><td>第六行第2個(gè)</td> </tr> </tbody> </table> </body> </html>
瀏覽器渲染出來(lái)(使用瀏覽器打開html文件)的樣子是這樣的~
以上總結(jié)就是colspan
實(shí)現(xiàn)橫向合并單元格,rowspan
實(shí)現(xiàn)縱向合并單元格~
呃嗯,既然我們知道了html
需要這兩個(gè)屬性值(也就是合并的行數(shù)或合并的列數(shù)),那麼就是要在sql中生成這兩個(gè)參數(shù)值然後提供給前端的同學(xué)使用哈,這是淺層意思,那麼深層意思是什麼呢???容我想想看。。。
- 對(duì)於橫向合并單元格
需要使用 case
+when
+then
語(yǔ)句判斷是否需要橫向合并(重要的是要給出橫向合并的數(shù)值),這樣想是合理的,可能造成的困擾可能是這樣做會(huì)造成sql
冗餘(當(dāng)然也是不得已而爲(wèi)之),當(dāng)然本節(jié)就不再講橫向合并單元格啦
- 對(duì)於縱向合并單元格
step1.👉 如果使用聚合
+窗口函數(shù)
來(lái)計(jì)算需要合并的相同的列數(shù),可能造成的問(wèn)題是生成的rowspan
對(duì)於相同列來(lái)説數(shù)值是一樣的(如下圖),這樣不可以欸~
step2.👉 。。。既然可以通過(guò)step1
生成窗口內(nèi)合并總數(shù)的數(shù)值,當(dāng)然也可以通過(guò)窗口函數(shù)來(lái)生成一個(gè)倒排序列
的列,哈哈😊,你似乎發(fā)現(xiàn)了什麼~~~,對(duì),將窗口合并總數(shù)的列與窗口內(nèi)倒排序的列做等值判斷,相等的不就是第一個(gè)合并數(shù)字列了。。。bingo
倒排序的窗口列
求總的列+倒排序的列
step3.👉 既然我們能做一個(gè)數(shù)據(jù)列的合并,也能做兩個(gè)列的合并(也可以是一個(gè)二級(jí)列,注意 order by
對(duì)合并行的影響哦),這裏簡(jiǎn)單各一個(gè)經(jīng)過(guò)層層包裝後的合并數(shù)值列生成,注意下圖的綠色部分哦😉
光説不練假把式,通過(guò)一下測(cè)試腳本試試囖😎~
2.2表結(jié)構(gòu)
drop table if EXISTS report2 ; CREATE TABLE report2 ( "id" varchar(10) primary key, "name" varchar(50), "price" numeric, "level2" varchar(50) , "level1" varchar(50) );
2.3表字段注釋
字段 | 注釋 |
---|---|
id | 主鍵 |
name | 商品名稱 |
price | 價(jià)格 |
level2 | 二級(jí)分類 |
level1 | 一級(jí)分類 |
2.4表數(shù)據(jù)
INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0015', '洗發(fā)露', '36', '洗護(hù)', '日用品'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0008', '香皂', '17.5', '洗護(hù)', '日用品'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0007', '薯?xiàng)l', '7.5', '垃圾食品', '零食'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0009', '方便面', '3.5', '垃圾食品', '零食'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0004', '辣條', '5.6', '垃圾食品', '零食'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0006', 'iPhone X', '9600', '小電器', '電器'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0003', '手表', '1237.55', '小電器', '電器'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0012', '電視', '3299', '大電器', '電器'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0016', '洗衣機(jī)', '4999', '大電器', '電器'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0013', '圍巾', '93', '配飾', '服裝配飾'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0017', '特步?jīng)鲂?, '499', '鞋子', '服裝配飾'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0001', 'NIKE新款鞋', '900', '鞋子', '服裝配飾'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0002', '外套', '110.9', '上衣', '服裝配飾'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0014', '作業(yè)本', '1', '紙張', '文具'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0005', '鉛筆', '7', '筆', '文具'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0010', '水杯', '27', '餐飲', '日用品'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0011', '毛巾', '15', '洗護(hù)', '日用品'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0018', '繪圖筆', '15', '筆', '文具'); INSERT INTO "report2"("id", "name", "price", "level2", "level1") VALUES ('0019', '汽水', '3.5', '其它', '零食');
3.🎉結(jié)果集最終求解
select t1.*, case when t_rank=t_count then t_count else null end as level1_row, case when tu_rank=tu_count then tu_count else null end as level2_row from ( select *, row_number() over(PARTITION by level1 order by level1 asc) t_rank, count(1) over (partition by level1) t_count, row_number() over(PARTITION by level1,level2 order by level1,level2 asc) tu_rank, count(1) over (partition by level1,level2) tu_count from report2 order by level1 ) t1 order by t1.level1,t_rank desc,t_count desc,tu_rank desc,tu_count desc;
_紅色_部分即為前端童鞋需要的合并數(shù)值哈🥰~
如果你能看懂以上問(wèn)題及求解的 sql
,恭喜你又升級(jí)啦😂
總結(jié)下::對(duì)問(wèn)題的分析✨
以及對(duì)問(wèn)題求解的思考🤔
很重要嘛,當(dāng)然還包含對(duì)postgresql
所提供工具的靈活使用 👉 總會(huì)產(chǎn)生意想不到的驚喜,哈哈😘~
到此這篇關(guān)于postgresql高級(jí)應(yīng)用之合并單元格的思路詳解的文章就介紹到這了,更多相關(guān)postgresql合并單元格內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決PostgreSQL Array使用中的一些小問(wèn)題
這篇文章主要介紹了解決PostgreSQL Array使用中的一些小問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01詳解如何優(yōu)化在PostgreSQL中對(duì)于日期范圍的查詢
在 PostgreSQL 中,處理日期范圍的查詢是常見的操作,然而,如果不進(jìn)行適當(dāng)?shù)膬?yōu)化,這些查詢可能會(huì)導(dǎo)致性能問(wèn)題,特別是在處理大型數(shù)據(jù)集時(shí),本文章將詳細(xì)討論如何優(yōu)化在 PostgreSQL 中對(duì)于日期范圍的查詢,需要的朋友可以參考下2024-07-07Linux下創(chuàng)建Postgresql數(shù)據(jù)庫(kù)的方法步驟
PostgreSQL 是一種非常復(fù)雜的對(duì)象-關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)(ORDBMS),也是目前功能最強(qiáng)大,特性最豐富和最復(fù)雜的自由軟件數(shù)據(jù)庫(kù)系統(tǒng)。下面這篇文章主要給大家介紹了關(guān)于在Linux下創(chuàng)建Postgresql數(shù)據(jù)庫(kù)的方法步驟,需要的朋友可以參考,下面來(lái)一起看看吧。2017-07-07Postgresql開啟遠(yuǎn)程訪問(wèn)的步驟全紀(jì)錄
postgre一般默認(rèn)為本地連接,不支持遠(yuǎn)程訪問(wèn),所以如果要開啟遠(yuǎn)程訪問(wèn),需要更改安裝文件的配置。下面這篇文章主要給大家介紹了關(guān)于Postgresql開啟遠(yuǎn)程訪問(wèn)的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2018-03-03解決postgreSql遠(yuǎn)程連接數(shù)據(jù)庫(kù)超時(shí)的問(wèn)題
這篇文章主要介紹了解決postgreSql遠(yuǎn)程連接數(shù)據(jù)庫(kù)超時(shí)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12

PostgreSQL存儲(chǔ)過(guò)程用法實(shí)戰(zhàn)詳解

postgresql 賦權(quán)語(yǔ)句 grant的正確使用說(shuō)明

PostgreSQL 數(shù)據(jù)庫(kù)性能提升的幾個(gè)方面