转自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]合并多行到一列(转)的更多相关文章

  1. SQL SERVER 字符合并多行为一列

    [字符合并多行为一列] 思路1:行转列,在与字符拼接(适用每组列数名相同) 思路2:转xml,去掉多余字符(适用所有) 假设兴趣表Hobbys Name Hobby 小张 打篮球 小张 踢足球 Nam ...

  2. poi导出excel合并单元格(包括列合并、行合并)

    1 工程所需jar包如下:commons-codec-1.5.jarcommons-logging-1.1.jarlog4j-1.2.13.jarjunit-3.8.1.jarpoi-3.9-2012 ...

  3. DataGridView合并单元格(一列或一行)

    #region"合并单元格的测试(一列或一行)" // int?是搜索一种类型(可空类型),普通的int不能为null,而用int?,其值可以为null //private int ...

  4. Java导出Excel表,POI 实现合并单元格以及列自适应宽度(转载)

    POI是apache提供的一个读写Excel文档的开源组件,在操作excel时常要合并单元格,合并单元格的方法是: sheet.addMergedRegion(new CellRangeAddress ...

  5. POI 实现合并单元格以及列自适应宽度

    POI是apache提供的一个读写Excel文档的开源组件,在操作excel时常要合并单元格,合并单元格的方法是: sheet.addMergedRegion(new CellRangeAddress ...

  6. 使用element-ui 组件动态合并table的行/列(第二次修改)

    这是第二次修改,在通过调用后台接口返回来的时候,发现了代码中的问题:现在将博客中错误的地方改过来,添加备注 文章需求:动态实现table表格中行/列的自动合并 使用框架及UI类库:Vue+Elemen ...

  7. EasyUi 合并单元格占列显示

    $("#TableContainer").datagrid({                url: '',                method: "get&q ...

  8. sql查询 ,多行数据合并成一行,并且显示合并后某一列的值拼接结果

    select  [value] = stuff((select ','+modmb003  from modmb detail where modmb=18 for xml path('')), 1, ...

  9. postgres serial创建自增列

    Sequence是数据库中一类特殊的对象,其用于生成唯一数字标识符.一个典型的应用场景就是手动生成一系列主键.Sequence和MySQL中的AUTO_INCREMENT的概念很像. 创建序列Sequ ...

随机推荐

  1. 版本控制git之一 - 仓库管理

    git 再开始这个话题之前,让我想起了一件很痛苦的事情,在我大学写毕业论文的时候,我当时的文件是这样保存的 毕业论文_初稿.doc 毕业论文_修改1.doc 毕业论文_修改2.doc 毕业论文_修改3 ...

  2. 百度地图SDK的使用

    最近看了一些SDK相关的东西,就心血来潮用了一下百度地图的sdk. 百度的文档真的很有问题,配置步骤也错漏很多. 1.首先百度地图的demo一直都是和最新的android studio版本不搭的,问题 ...

  3. LNK2026: 模块对于 SAFESEH 映像是不安全的<转>

    转自VC错误:http://www.vcerror.com/?p=162 错误描述: 在使用VS2012编译工程时,提示错误:" error LNK2026: 模块对于 SAFESEH 映像 ...

  4. MySQL Innodb 神秘消失

    问题描述: 早晨接到 Zabbix 报警,提示 Host: 10.10.1.2, MySQL 主从同步失败. 登录服务器查看具体情况. shell > mysql mysql> show ...

  5. 【306】通过ArcPy编写ArcToolbox

    参考:使用 Python 创建工具 参考:在 Python 工具箱中定义参数数据类型 基本步骤如下: (1)创建一个 Python 脚本,并保存成 .py 文件. (2)创建一个自定义工具箱(.tbx ...

  6. 团队合作的Ground Rules

    在每个Sprint中,我们会为Sprint的确定DOD(Definition of Done,完成的定义).在团队成员合作的过程中,我们也需要定义合作规则,这就是Ground rules,就像小学生守 ...

  7. [iOS]在xcode的iOS虚拟机中对BLE(蓝牙4.0)进行调试

    本文档的主要内容可参考苹果官方资料: http://developer.apple.com/library/ios/#technotes/tn2295/_index.html 1. 买一个CSR蓝牙4 ...

  8. 关于PHP如何用实现防止用户在浏览器上使用后退功能重复提交输入

    $(function(){ if(window.history && window.history.pushState){ $(window).on('popstate',functi ...

  9. Open MSDN document directly without Visual Studio

    "C:\Program Files (x86)\Microsoft Help Viewer\v2.2\HlpViewer.exe" /catalogName VisualStudi ...

  10. Anisotropic Specular Shader

    [Anisotropic Specular] Anisotropic Specular(各向异性反射)模拟表面凹槽的方向性.就像CD表面一样.CD的表面凹槽是有方向的. BlinnPhong中Spec ...