书籍是全世界的营养品。生活里没有书籍,就好像没有阳光;智慧里没有书籍,就好像鸟儿没有翅膀。
目录 / 分类
数据库基础
数据库原理
SQL语言
网络原理
DB4O
Access
基础知识
驱动及连接
试题参考
技术手册
应用案例
常见问题
SQLServer
基础知识
驱动及连接
管理工具
技术手册
应用案例
常见问题
MySQL
基础知识
驱动连接
管理工具
技术手册
应用案例
常见问题
SQLite
基础知识
驱动及连接
管理工具
技术手册
应用案例
常见问题
Oracle
基础知识
驱动连接
管理工具
技术手册
应用案例
常见问题
PostgreSQL
基础知识
驱动及连接
管理工具
技术手册
应用案例
常见问题
移动应用
JavaME
Android
微信开发
经验分享
Java组件
Java开发
应用办公
常见问题解决
Delphi
硬件故障解决
WEB
HTML5
Javascript
速查表
文件同步
服务器配置
Apache
Tomcat
Resin
协议&概念
IIS&ASP
win&linux
Absolute Database
nginx
OpenFire
Redis
freeswitch
网文摘录
IT杂谈
网文转载
行业新闻
热点推荐
下载中心
软件下载
CUBRID数据库
介绍及使用
验证/二维/条形码
验证码原理及实现
二维码相关
条形码相关
在线二维码生成
在线条形码生成
当前位置:
首页
>
PostgreSQL
>
应用案例
POSTGRESQL交叉表的实现
这里我来演示下在POSTGRESQL里面如何实现交叉表的展示,至于什么是交叉表,我就不多说了,度娘去哦。
原始表数据如下:
t_girl
=
#
select
*
from
score
;
name
|
subject
|
score
-------+---------+-------
Lucy
|
English
|
100
Lucy
|
Physics
|
90
Lucy
|
Math
|
85
Lily
|
English
|
95
Lily
|
Physics
|
81
Lily
|
Math
|
84
David
|
English
|
100
David
|
Physics
|
86
David
|
Math
|
89
Simon
|
English
|
90
Simon
|
Physics
|
76
Simon
|
Math
|
79
(
12
rows
)
Time
:
2
.
066 ms
想要实现以下的结果:
name
|
English
|
Physics
|
Math
-------+---------+---------+------
Simon
|
90
|
76
|
79
Lucy
|
100
|
90
|
85
Lily
|
95
|
81
|
84
David
|
100
|
86
|
89
大致有以下几种方法:
1、用标准SQL展现出来
t_girl
=
#
select
name
,
t_girl
-
#
sum
(
case when subject
=
'English'
then
score
else
0
end
)
as
"English"
,
t_girl
-
#
sum
(
case when subject
=
'Physics'
then
score
else
0
end
)
as
"Physics"
,
t_girl
-
#
sum
(
case when subject
=
'Math'
then
score
else
0
end
)
as
"Math"
t_girl
-
#
from
score
t_girl
-
#
group
by
name
order
by
name
desc
;
name
|
English
|
Physics
|
Math
-------+---------+---------+------
Simon
|
90
|
76
|
79
Lucy
|
100
|
90
|
85
Lily
|
95
|
81
|
84
David
|
100
|
86
|
89
(
4
rows
)
Time
:
1
.
123 ms
2、用PostgreSQL 提供的第三方扩展 tablefunc 带来的函数实现
以下函数crosstab 里面的SQL必须有三个字段,name, 分类以及分类值来作为起始参数,必须以name,分类值作为输出参数。
t_girl
=
#
SELECT
*
FROM
crosstab
(
'select name,subject,score from score order by name desc'
,
$
$
values
(
'English'
:
:
text
)
,
(
'Physics'
:
:
text
)
,
(
'Math'
:
:
text
)
$
$
)
AS
score
(
name text
,
English int
,
Physics int
,
Math int
)
;
name
|
english
|
physics
|
math
-------+---------+---------+------
Simon
|
90
|
76
|
79
Lucy
|
100
|
90
|
85
Lily
|
95
|
81
|
84
David
|
100
|
86
|
89
(
4
rows
)
Time
:
2
.
059 ms
3、用PostgreSQL 自身的聚合函数实现
t_girl
=
#
select
name
,
split_part
(
split_part
(
tmp
,
','
,
1
)
,
':'
,
2
)
as
"English"
,
t_girl
-
#
split_part
(
split_part
(
tmp
,
','
,
2
)
,
':'
,
2
)
as
"Physics"
,
t_girl
-
#
split_part
(
split_part
(
tmp
,
','
,
3
)
,
':'
,
2
)
as
"Math"
t_girl
-
#
from
t_girl
-
#
(
t_girl
(
#
select
name
,
string_agg
(
subject
|
|
':'
|
|
score
,
','
)
as
tmp
from
score
group
by
name
order
by
name
desc
t_girl
(
#
)
as
T
;
name
|
English
|
Physics
|
Math
-------+---------+---------+------
Simon
|
90
|
76
|
79
Lucy
|
100
|
90
|
85
Lily
|
95
|
81
|
84
David
|
100
|
86
|
89
(
4
rows
)
Time
:
2
.
396 ms
4、 存储函数实现
create
or
replace
function
func_ytt_crosstab_py
(
)
returns setof ytt_crosstab
as
$ytt$
for
row
in
plpy
.
cursor
(
"select name,string_agg(subject||':'||score,',') as tmp from score group by name order by name desc"
)
:
a
=
row
[
'tmp'
]
.
split
(
','
)
yield
(
row
[
'name'
]
,
a
[
0
]
.
split
(
':'
)
[
1
]
,
a
[
1
]
.
split
(
':'
)
[
1
]
,
a
[
2
]
.
split
(
':'
)
[
1
]
)
$ytt$ language plpythonu
;
t_girl
=
#
select
name
,
english
,
physics
,
math
from
func_ytt_crosstab_py
(
)
;
name
|
english
|
physics
|
math
-------+---------+---------+------
Simon
|
90
|
76
|
79
Lucy
|
100
|
90
|
85
Lily
|
95
|
81
|
84
David
|
100
|
86
|
89
(
4
rows
)
Time
:
2
.
687 ms
5、 用PLPGSQL来实现
t_girl
=
#
create
type
ytt_crosstab
as
(
name text
,
English text
,
Physics text
,
Math text
)
;
CREATE
TYPE
Time
:
22
.
518 ms
create
or
replace
function
func_ytt_crosstab
(
)
returns setof ytt_crosstab
as
$ytt$
declare v_name text
:
=
''
;
v_english text
:
=
''
;
v_physics text
:
=
''
;
v_math text
:
=
''
;
v_tmp_result text
:
=
''
;
declare cs1 cursor
for
select
name
,
string_agg
(
subject
|
|
':'
|
|
score
,
','
)
from
score
group
by
name
order
by
name
desc
;
begin
open cs1
;
loop
fetch cs1
into
v_name
,
v_tmp_result
;
exit
when
not
found
;
v_english
=
split_part
(
split_part
(
v_tmp_result
,
','
,
1
)
,
':'
,
2
)
;
v_physics
=
split_part
(
split_part
(
v_tmp_result
,
','
,
2
)
,
':'
,
2
)
;
v_math
=
split_part
(
split_part
(
v_tmp_result
,
','
,
3
)
,
':'
,
2
)
;
return
query
select
v_name
,
v_english
,
v_physics
,
v_math
;
end
loop
;
end
;
$ytt$ language plpgsql
;
t_girl
=
#
select
name
,
English
,
Physics
,
Math
from
func_ytt_crosstab
(
)
;
name
|
english
|
physics
|
math
-------+---------+---------+------
Simon
|
90
|
76
|
79
Lucy
|
100
|
90
|
85
Lily
|
95
|
81
|
84
David
|
100
|
86
|
89
(
4
rows
)
Time
:
2
.
127 ms
上一篇:Postgresql数据库运维笔记
下一篇:PostgreSQL数据库创建多字段表以及插入多行数据
本站文章内容,部分来自于互联网,若侵犯了您的权益,请致邮件chuanghui423#sohu.com(请将#换为@)联系,我们会尽快核实后删除。
Copyright © 2006-2023 DBMNG.COM All Rights Reserved. Powered by
DEVSOARTECH
豫ICP备11002312号-2
豫公网安备 41010502002439号