转自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. day9-数据库操作与Paramiko模块

    堡垒机前戏 开发堡垒机之前,先来学习Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接: 1 ...

  2. LCS(最长公共子序列)动规算法正确性证明

    今天在看代码源文件求diff的原理的时候看到了LCS算法.这个算法应该不陌生,动规的经典算法.具体算法做啥了我就不说了,不知道的可以直接看<算法导论>动态规划那一章.既然看到了就想回忆下, ...

  3. Easyui Datagrid 的Combobox 如何动态修改下拉选项,以及值的转换

    我是先将下拉选项的值通过datagrid的url查出来了,在每一行的row中 //项目结果选项卡的列表    $('#project_table').datagrid({        width : ...

  4. 【314】putty 自动登录

    putty是一款好用的远程登录linux服务器软件,但每次输入用户名密码毕竟有些烦人,这里教你免用户名密码登陆. 本教程通过 *.bat 文件进行添加参数,下面为相应的代码: 方法一:(直接将密码/用 ...

  5. C#中的goto

    int i = 9;if (i % 2 == 0) goto Found;else goto NoFound; NoFound:            Console.WriteLine(i.ToSt ...

  6. aws s3 python sdk

    http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.get_object abort_multipar ...

  7. fsync性能问题

    最近在测试种发现程序里调用fsync刷文件到磁盘时,开销只有几百微秒,于是对fsync相关机制进行了一番调查. 磁盘(或RAID卡)自身通常会有硬件缓存机制,对于写操作,有write back和wri ...

  8. html学习代码

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  9. SpringBoot Actuator & SpringBoot Admin

    SpringBoot Actuator提供了很多监控和管理你的spring boot应用的HTTP或者JMX端点,并且你可以有选择地开启和关闭部分功能. 当你的spring boot应用中引入依赖之后 ...

  10. linux系统命令行基本组成元素

    一.shell prompt(PS1) 命令行提示符 1. 游标(coursor) 当你成功登录进一个文字界面之后,大部份情形下,你会在荧幕上看到一个不断闪烁的方块或底线(视不同版本而别),我们称之为 ...