PostgreSQL psql 绘制饼图

本文涉及的产品
云原生数据库 PolarDB 分布式版,标准版 2核8GB
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS PostgreSQL Serverless,0.5-4RCU 50GB 3个月
推荐场景:
对影评进行热评分析
简介: 标签PostgreSQL , SQL , PLPGSQL , 绘制饼图背景图像相比文字是更容易被理解的东西,在BI可视化领域,经常会使用图像来代替数值,展示一些信息,例如柱状图、饼图、线图等。

标签

PostgreSQL , SQL , PLPGSQL , 绘制饼图


背景

图像相比文字是更容易被理解的东西,在BI可视化领域,经常会使用图像来代替数值,展示一些信息,例如柱状图、饼图、线图等。

AWR文字报告里面,如果多几个图像来代替列表,其实也是不错的。

那么SQL能直接画图吗,把一行行的结果,转换成图像。

例如

1、TOP SQL的总耗时占比饼图。

2、数据库对象类型占比饼图。

3、数据库空间占比饼图。

4、TOP对象的空间占。

PostgreSQL凭借丰富的SQL语法,画图,小CASE。

画图SQL举例

https://wiki.postgresql.org/wiki/Pie_Charts

使用psql终端绘图的方法如下:

1、设置变量,饼图的宽,高,代表不同颜色的字符等。

\set width  80  
\set height 25  
\set radius 1.0  
\set colours '''#;o:X"@+-=123456789abcdef'''  

2、绘图的DEMO SQL,将4行记录转换为饼图

这4行记录如下:

VALUES ('red',1),  
                ('blue',2),  
                ('orange',3),  
                ('white',4)  
        )  

绘图SQL如下

WITH slices AS (  
 SELECT  CAST(ROW_NUMBER() OVER () AS INTEGER) AS slice,  
         name,   
	 VALUE,  
	 100.0 * VALUE / SUM(VALUE) OVER () AS percentage,  
	 2*PI() * SUM(VALUE) OVER (ROWS unbounded preceding)   
                / SUM(VALUE) OVER () AS radians  
   FROM (VALUES ('red',1),  
                ('blue',2),  
                ('orange',3),  
                ('white',4)  
        ) AS DATA(name,VALUE))  
(  
  SELECT array_to_string(array_agg(c),'') AS pie_chart  
    FROM (  
    SELECT x, y,  
           CASE WHEN NOT (SQRT(pow(x, 2) + pow(y, 2))   
                            BETWEEN :radius*1/10 AND :radius)  
                THEN ' '  
                ELSE SUBSTRING(:colours,  
                               (SELECT MIN(slice)   
                                  FROM slices   
                                 WHERE radians >= PI() + atan2(y,-x)),  
                               1)  
                END AS c  
      FROM (SELECT 2.0*generate_series(0,:width)/:width-1.0)   AS x(x),  
           (SELECT 2.0*generate_series(0,:height)/:height-1.0) AS y(y)  
     ORDER BY y,x  
  ) AS xy  
 GROUP BY y  
 ORDER BY y  
)  
UNION ALL   
SELECT repeat(SUBSTRING(:colours,slice,1), 2) || '  ' ||   
       name || ': ' ||   
       VALUE || '  (' || round(percentage,0) || '%)'   
  FROM slices;  

3、图像结果如下

  
                                     pie_chart                                       
-----------------------------------------------------------------------------------  
                                         ;                                          
                          oooo;;;;;;;;;;;;;;;;;;;;;;;;;;;                           
                    ooooooooooo;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                     
                oooooooooooooooo;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                 
            ooooooooooooooooooooo;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;             
         ooooooooooooooooooooooooo;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;          
       oooooooooooooooooooooooooooo;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;######        
      oooooooooooooooooooooooooooooo;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;###########       
    ooooooooooooooooooooooooooooooooo;;;;;;;;;;;;;;;;;;;;;;;;##################     
   ooooooooooooooooooooooooooooooooooo;;;;;;;;;;;;;;;;;;;#######################    
  ooooooooooooooooooooooooooooooooooooo;;;;;;;;;;;;;;############################   
  oooooooooooooooooooooooooooooooooooooo;;;;;;;;#################################   
  oooooooooooooooooooooooooooooooooooo       ####################################   
  oooooooooooooooooooooooooooooooooooo       ::::::::::::::::::::::::::::::::::::   
  ooooooooooooooooooooooooooooooooo::::::::::::::::::::::::::::::::::::::::::::::   
  oooooooooooooooooooooooooooo:::::::::::::::::::::::::::::::::::::::::::::::::::   
   ooooooooooooooooooooooo::::::::::::::::::::::::::::::::::::::::::::::::::::::    
    oooooooooooooooooo:::::::::::::::::::::::::::::::::::::::::::::::::::::::::     
      ooooooooooo::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::       
       oooooo:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::        
         :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::          
            :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::             
                :::::::::::::::::::::::::::::::::::::::::::::::::::                 
                    :::::::::::::::::::::::::::::::::::::::::::                     
                          :::::::::::::::::::::::::::::::                           
                                         :                                          
 ##  red: 1  (10%)  
 ;;  blue: 2  (20%)  
 oo  orange: 3  (30%)  
 ::  white: 4  (40%)  
(30 rows)  

是不是很有意思?

将绘图SQL转换为函数接口提供任意调用

1、函数接口如下

create or replace function gen_charts(  
  sql text,  -- SQL,返回两列,第一列为描述,第二列为这个描述的数值  
  width int default 80,   
  height int default 25,   
  radius numeric default 1.0,   -- 换成float8类型,打印实心饼图
  colours text default '#;o:X"@+-=123456789abcdef'    
) returns setof text as $$  
declare  
begin  
return query execute format(  
$_$  
WITH slices AS (  
 SELECT  CAST(ROW_NUMBER() OVER () AS INTEGER) AS slice,  
         name,   
	 VALUE,  
	 100.0 * VALUE / SUM(VALUE) OVER () AS percentage,  
	 2*PI() * SUM(VALUE) OVER (ROWS unbounded preceding)   
                / SUM(VALUE) OVER () AS radians  
   FROM (%s  
        ) AS DATA(name,VALUE))  
(  
  SELECT array_to_string(array_agg(c),'') AS pie_chart  
    FROM (  
    SELECT x, y,  
           CASE WHEN NOT (SQRT(pow(x, 2) + pow(y, 2))   
                            BETWEEN %s*1/10 AND %s)  
                THEN ' '  
                ELSE SUBSTRING(%L,  
                               (SELECT MIN(slice)   
                                  FROM slices   
                                 WHERE radians >= PI() + atan2(y,-x)),  
                               1)  
                END AS c  
      FROM (SELECT 2.0*generate_series(0,%s)/%s-1.0) AS x(x),  
           (SELECT 2.0*generate_series(0,%s)/%s-1.0) AS y(y)  
     ORDER BY y,x  
  ) AS xy  
 GROUP BY y  
 ORDER BY y  
)  
UNION ALL   
SELECT repeat(SUBSTRING(%L,slice,1), 2) || '  ' ||   
       name || ': ' ||   
       VALUE || '  (' || round(percentage,0) || '%%)'   
  FROM slices;  
$_$, sql, radius, radius, colours, width, width, height, height, colours);  
  
return;  
end;  
$$ language plpgsql strict;  

绘图函数接口使用举例

1、打印当前数据库中的不同对象类型占比

postgres=# select * from gen_charts('select relkind,count(*) from pg_class group by relkind');  
                                    gen_charts                                     
-----------------------------------------------------------------------------------
                                         ;                                        
                          ;;;;;;;;;;;;;;;;;;;;;;;;;;;####                         
                    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;###########                   
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;################               
            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#####################           
         ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#########################        
       ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;############################      
      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;##############################     
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#################################   
   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;###################################  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;##################################### 
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;###################################### 
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;       #################################### 
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oo       o::::::::::::::::::::::::::::::::::: 
  ;;;;;;;;;;;;;;;;;;;;;;;ooooooooooooooooooooooooooooo::::::::::::::::::::::::::: 
  ;;;;;;;;;;;;oooooooooooooooooooooooooooooooooooooooooooooooo::::::::::::::::::: 
   ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo::::::::::  
    oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo:   
      ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo     
       ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo      
         ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo        
            ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo           
                ooooooooooooooooooooooooooooooooooooooooooooooooooo               
                    ooooooooooooooooooooooooooooooooooooooooooo                   
                          ooooooooooooooooooooooooooooooo                         
                                         o                                        
 ##  r: 71  (20%)
 ;;  v: 119  (34%)
 oo  i: 138  (40%)
 ::  t: 20  (6%)
 XX  c: 1  (0%)
(31 rows)

2、打印大于8K的对象,空间排行前十的对象,他们分别的占比

postgres=# select * from gen_charts('select relname , pg_relation_size(oid) from pg_class where pg_relation_size(oid) > 8192 order by pg_relation_size(oid) desc limit 10'); 
                                    gen_charts                                     
-----------------------------------------------------------------------------------
                                         #                                        
                          ###############################                         
                    ###########################################                   
                ###################################################               
            ###########################################################           
         #################################################################        
       #####################################################################      
      #######################################################################     
    ###########################################################################   
   #############################################################################  
  ############################################################################### 
  ############################################################################### 
  ####################################       #################################### 
  ####################################       ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
  ##############################################;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
  ###################################################;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
   #######################################################;;;;;;;;;;;;;;;;;;;;;;  
    ##########################################################;;;;;;;;;;;;;;;;;   
      #############################################################;;;;;;;;;;     
       #################################################################;;;;      
         #################################################################        
            ###########################################################           
                ###################################################               
                    ###########################################                   
                          ###############################                         
                                         #                                        
 ##  idx_c_1: 2359795712  (90%)
 ;;  c: 248135680  (10%)
 oo  pg_proc: 663552  (0%)
 ::  pg_depend: 548864  (0%)
 XX  pg_attribute: 458752  (0%)
 ""  pg_depend_reference_index: 458752  (0%)
 @@  pg_depend_depender_index: 417792  (0%)
 ++  pg_toast_2618: 417792  (0%)
 --  pg_statistic: 385024  (0%)
 ==  pg_proc_proname_args_nsp_index: 294912  (0%)
(36 rows)

3、打印不同数据库的空间占比

postgres=# select * from gen_charts('select datname, pg_database_size(datname) from pg_database group by 1');  
                                    gen_charts                                     
-----------------------------------------------------------------------------------
                                         #                                        
                          ###############################                         
                    ###########################################                   
                ###################################################               
            ###########################################################           
         #################################################################        
       #####################################################################      
      #######################################################################     
    ###########################################################################   
   #############################################################################  
  ############################################################################### 
  ############################################################################### 
  ####################################       #################################### 
  ####################################       #################################### 
  ############################################################################### 
  ############################################################################### 
   #############################################################################  
    ###########################################################################   
      #######################################################################     
       #####################################################################      
         #################################################################        
            ###########################################################           
                ###################################################               
                    ###########################################                   
                          ###############################                         
                                         #                                        
 ##  postgres: 2616839287  (99%)
 ;;  template0: 7741955  (0%)
 oo  template1: 7741955  (0%)
(29 rows)

参考

http://code.openark.org/blog/mysql/sql-pie-chart

https://wiki.postgresql.org/wiki/Pie_Charts

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
2月前
|
SQL 关系型数据库 Linux
PostgreSQL基础之psql的使用
PostgreSQL基础之psql的使用
51 0
|
5月前
|
关系型数据库 分布式数据库 数据库
PolarDB for PostgreSQL报错问题之psql连接数据库报错如何解决
PolarDB for PostgreSQL是基于PostgreSQL开发的一款云原生关系型数据库服务,它提供了高性能、高可用性和弹性扩展的特性;本合集将围绕PolarDB(pg)的部署、管理和优化提供指导,以及常见问题的排查和解决办法。
|
5月前
|
关系型数据库 Linux 数据安全/隐私保护
PostgreSQL【部署 02】在线安装PostgreSQL(Some psql features might not work 问题处理+角色密码设置+配置远程访问)
PostgreSQL【部署 02】在线安装PostgreSQL(Some psql features might not work 问题处理+角色密码设置+配置远程访问)
74 0
PostgreSQL【部署 02】在线安装PostgreSQL(Some psql features might not work 问题处理+角色密码设置+配置远程访问)
|
前端开发 关系型数据库 数据库
使用psql操作PostgreSQL数据库
使用psql操作PostgreSQL数据库
92 0
|
SQL Oracle 关系型数据库
【postgreSQL】psql工具特有的快捷命令
【postgreSQL】psql工具特有的快捷命令
8881 1
|
SQL 存储 Oracle
【postgreSQL】psql工具特有的快捷命令2
【postgreSQL】psql工具特有的快捷命令2
156 0
|
关系型数据库 PostgreSQL
使用psql连接 postgresql失败
使用psql链接postgresql服务失败,telnet这个地址和端口有没有反映。
150 0
|
SQL 存储 移动开发
PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(四)|学习笔记
快速学习3 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(四)
454 0
 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(四)|学习笔记
|
SQL 关系型数据库 数据库
3 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(三)|学习笔记
快速学习3 PostgreSQL psql的使用,SQL语法,数据类型,递归SQL用法(三)
352 0
|
SQL 关系型数据库 数据库
PostgreSQL Tutorial | psql的使用
本文提供一系列常用的psql命令,能够帮助你快速和高效的从数据库中获取数据。 Connect to PostgreSQL database 1.使用psql 连接到数据库,回车后会提示你输入密码 [postgres@localhost ~]$ psql -dtest -Upostgres -W Password for user postgres: psql (10.
1693 0

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版