[Postgres]合并多行到一列(转)
转自http://csk83.sinaapp.com/?p=104
在实际应用中常常遇见这样的情况,见下表,我们现在需要统计出来每年每个人的工资总和以及发放月份。
| user_name | year | month | money |
|---|---|---|---|
| 张三 | 2011 | 1 | 900 |
| 张三 | 2011 | 2 | 1200 |
| 张三 | 2011 | 5 | 1100 |
| 张三 | 2011 | 6 | 1300 |
| 李四 | 2011 | 1 | 1100 |
| 李四 | 2011 | 3 | 1200 |
即我们要得到下面表的结果
| user_name | year | monthes | total money |
|---|---|---|---|
| 张三 | 2011 | 1,2,5,6 | 4500 |
| 李四 | 2011 | 1,3 | 2300 |
首先我们想到的是有这样的SQL语句:
SELECT user_name,year,myfunction(month) AS monthes, SUM(money) AS total_money FROM table GROUP BY user_name,year;
像count或者sum一样吧数据表中的某个字段按照需要拼接起来,但是在PostgreSQL好像没有直接的方法来实现(或许有笔者没有发现,正因为没有发现所以笔者才研究了半天得到下面的心得)。
方法一:在PostgreSQL中如果不自定义函数直接用SQL来实现
SELECT t1.user_name, t1.year, ARRAY_TO_STRING(array(SELECT t2.month FROM table t2 WHERE t2.user_name=t1.user_name AND t2.year=t1.year), ‘,’) AS monthes, SUM(t1.money) AS total_money FROM table t1 WHERE 1 GROUP BY t1.user_name, t1.year;
这里主要是用了PostgreSQL的内置数组函数array_to_string把数组拼接成字符串。
方法二:自己写一个聚合函数csk_test来实现
结合上面array_to_sting的用法,根据聚合函数定义方法研究出用聚合函数来实现的方法:
– 1 开启plpgsql的支持,如果没有需要运行下面两行SQL开启plpgsql支持
CREATE FUNCTION plpgsql_call_handler() RETURNS language_handler AS ‘$libdir/plpgsql’ LANGUAGE C;
CREATE TRUSTED LANGUAGE plpgsql HANDLER “plpgsql_call_handler”;
– 2 创建函数
—- 2.1 收集数据到一个数组
CREATE FUNCTION csk_test_start(a TEXT[], s TEXT) RETURNS TEXT[] AS $$
BEGIN
RETURN a || s;
END;
$$ LANGUAGE plpgsql;
—- 2.2 最后处理函数,把数组转换成字符串输出
CREATE FUNCTION csk_test_final(a TEXT[]) RETURNS TEXT AS $$
BEGIN
RETURN array_to_string(a, ‘,’);
END;
$$ LANGUAGE plpgsql;
– 3 创建聚集函数
CREATE AGGREGATE csk_test(
BASETYPE = TEXT,
SFUNC = csk_test_start,
STYPE = TEXT[],
FINALFUNC = csk_test_final
);
现在我们再次用本文开始的SQL就可以实现我们的要求了
SELECT user_name,year,csk_test(CAST(month to varchar)) AS monthes, SUM(money) AS total_money FROM table GROUP BY user_name,year;
需要注意的是,上面的聚集函数接收的数据类型是text,所以在用的时候month整型转换成了varchar类型,当然也可以直接修改上面的代码让它们的类型一致。聚合函数在文本字段的处理上在PostgreSQL 8.4上测试通过了,至于数字类型其他类型转换后是否能行没有测试过。
方法二是通过聚合函数引用自定义函数来实现的,其实还可以直接调用系统函数array_append来实现:
CREATE AGGREGATE csk_test(
basetype = integer,
sfunc = array_append,
stype = integer[],
initcond = ‘{}’
);
可参考http://www.postgresql.org/docs/9.1/static/functions-array.html
[Postgres]合并多行到一列(转)的更多相关文章
- SQL SERVER 字符合并多行为一列
[字符合并多行为一列] 思路1:行转列,在与字符拼接(适用每组列数名相同) 思路2:转xml,去掉多余字符(适用所有) 假设兴趣表Hobbys Name Hobby 小张 打篮球 小张 踢足球 Nam ...
- poi导出excel合并单元格(包括列合并、行合并)
1 工程所需jar包如下:commons-codec-1.5.jarcommons-logging-1.1.jarlog4j-1.2.13.jarjunit-3.8.1.jarpoi-3.9-2012 ...
- DataGridView合并单元格(一列或一行)
#region"合并单元格的测试(一列或一行)" // int?是搜索一种类型(可空类型),普通的int不能为null,而用int?,其值可以为null //private int ...
- Java导出Excel表,POI 实现合并单元格以及列自适应宽度(转载)
POI是apache提供的一个读写Excel文档的开源组件,在操作excel时常要合并单元格,合并单元格的方法是: sheet.addMergedRegion(new CellRangeAddress ...
- POI 实现合并单元格以及列自适应宽度
POI是apache提供的一个读写Excel文档的开源组件,在操作excel时常要合并单元格,合并单元格的方法是: sheet.addMergedRegion(new CellRangeAddress ...
- 使用element-ui 组件动态合并table的行/列(第二次修改)
这是第二次修改,在通过调用后台接口返回来的时候,发现了代码中的问题:现在将博客中错误的地方改过来,添加备注 文章需求:动态实现table表格中行/列的自动合并 使用框架及UI类库:Vue+Elemen ...
- EasyUi 合并单元格占列显示
$("#TableContainer").datagrid({ url: '', method: "get&q ...
- sql查询 ,多行数据合并成一行,并且显示合并后某一列的值拼接结果
select [value] = stuff((select ','+modmb003 from modmb detail where modmb=18 for xml path('')), 1, ...
- postgres serial创建自增列
Sequence是数据库中一类特殊的对象,其用于生成唯一数字标识符.一个典型的应用场景就是手动生成一系列主键.Sequence和MySQL中的AUTO_INCREMENT的概念很像. 创建序列Sequ ...
随机推荐
- 使用被动混合内容的方式来跨越浏览器会阻断HTTPS上的非安全请求(HTTP)请求的安全策略抓包详解
/*通过传入loginId在token中附加loginId参数,方便后续读取指定缓存中的指定用户信息*/ GET /multitalk/takePhone.php?loginId=4edc153568 ...
- spring-boot-starter-security Spring Boot中集成Spring Security
spring security是springboot支持的权限控制系统. security.basic.authorize-mode 要使用权限控制模式. security.basic.enabled ...
- STL : List使用时应注意的问题
这篇文章所述只是本人遇到的问题,仅供参考. #include<list> #include<iostream> using namespace std; class Foo { ...
- UNITY 内存问题资料收集
1,https://blog.csdn.net/wetest_tencent/article/details/52130703 2,http://blog.51cto.com/13638120/208 ...
- MantisBT 缺陷管理系统
简介: 公司需要一套缺陷管理系统,这种系统比较热门的有 Jira.Redmine.MantisBT 等. 这次来整理一下 MantisBT,正好公司需要,以前的文档又丢失了. 下载地址:http:// ...
- 【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 13—Clustering 聚类
Lecture 13 聚类 Clustering 13.1 无监督学习简介 Unsupervised Learning Introduction 现在开始学习第一个无监督学习算法:聚类.我们的数据没 ...
- mysql varchar类型转换int类型
select * from gyzd_yysinfo order by cast(yysid as SIGNED INTEGER) 或者 select * from gyzd_yysinfo orde ...
- 使用火狐浏览器访问双向认证的k8s api
首先 不能在火狐里对要访问的网址添加例外 打开 选项->高级->查看证书->证书机构->导入.先择服务端ca.crt后根据提示导入证书 生成p12文件 openssl pkcs ...
- Linux实战教学笔记43:squid代理与缓存实践(二)
第6章 squid代理模式案例 6.1 squid传统正向代理生产使用案例 6.1.1 squid传统正向代理两种方案 (1)普通代理服务器 作为代理服务器,这是SQUID的最基本功能:通过在squi ...
- Solr集群—SolrCloud
1. 学习计划 1.solr集群搭建 2.使用solrj管理solr集群 3.把搜索功能切换到集群版 2. 什么是SolrCloud SolrCloud(solr 云)是Solr提供的分布式搜 ...