上节我们学习使用 tablefunc实现交叉表查询。但还不够强大,能不能展示每月的平均成绩或总成绩,或同时显示平均成绩或总成绩,本文带你一步一步进行实现。

示例数据

我们示例表是学生成绩表,包括学生姓名、科目、成绩、考试日期:

create table evaluations(stu_name varchar(60),subject varchar(60),eval_result numeric(3,1),eval_day    date
);insert into evaluations(stu_name,subject,eval_result,eval_day) values
('smith', 'music',  7.0,    '2016-03-01'),
('smith', 'maths',  4.0,    '2016-03-01'),
('smith', 'history',    9.0,    '2016-03-22'),
('smith', 'chinese',    7.0,    '2016-03-15'),
('smith',     'geography',  9.0,    '2016-03-04'),
('peter', 'music',  2.0,'2016-03-01'),
('peter', 'maths',  10.0,   '2016-03-01'),
('peter', 'history',    7.0,    '2016-03-22'),
('peter', 'chinese',    4.0,    '2016-03-15'),
('peter', 'geography',  10.0,   '2016-03-04')-- select * from evaluations e

每月平均成绩

我们通过 学生名称和月份进行分组:

select stu_name, extract (month from eval_day) eval_month, round(avg(eval_result),2) avg_result
from  evaluations
group by stu_name , extract (month from eval_day)

显示结果:

stu_name eval_month avg_result
smith 3.0 8.33
smith 4.0 5.50
peter 3.0 6.60

下面我们使用 实现交叉表查询:

select * from crosstab(
$$
select stu_name, extract (month from eval_day) eval_month, round(avg(eval_result),2) avg_result
from  evaluations
group by stu_name , extract (month from eval_day)
order by 1,2
$$
) as avg_result(stu_name text, month3_avg numeric, month4_avg numeric)

执行返回错误:

SQL 错误 [42804]: 错误: invalid return type详细:SQL rowid datatype does not match return rowid datatype.

这是因为 crosstab 不能智能识别返回的月份信息,我们需要通过第二个参数进行显示设定,crosstab 完整语法如下:

crosstab(text source_sql, text category_sql)

修改上面代码:

select * from crosstab(
$$
select stu_name, extract (month from eval_day) eval_month,round(avg(eval_result),2) avg_result
from  evaluations
group by stu_name , extract (month from eval_day)
order by 1,2
$$
,'select distinct  extract (month from eval_day) eval_month from evaluations order by 1'
) as avg_result(stu_name text, month3_avg numeric, month4_avg numeric)

再次执行返回:

stu_name month3_avg month4_avg
peter 6.60
smith 8.33 5.50

与我们的预期一致。这时我们可能会想交叉表能不能同时显示每月的平均成绩和总成绩。

每月平均成绩与总成绩

上面已经完成了月度平均成绩的计算,同理计算月度总成绩就简单了:

select * from crosstab(
$$
select stu_name, extract (month from eval_day) eval_month,round(sum(eval_result),2) sum_result
from  evaluations
group by stu_name , extract (month from eval_day)
order by 1,2
$$
,'select distinct  extract (month from eval_day) eval_month from evaluations order by 1'
) as avg_result(stu_name text, month3_sum numeric, month4_sum numeric)

执行结果:

stu_name month3_sum month4_sum
peter 33.00
smith 25.00 11.00

既然两者都已经计算处理,那么我们通过with进行组合:

with avg_data as (select * from crosstab($$select stu_name, extract (month from eval_day) eval_month,round(avg(eval_result),2) avg_resultfrom  evaluationsgroup by stu_name , extract (month from eval_day) order by 1,2$$,'select distinct  extract (month from eval_day) eval_month from evaluations order by 1') as avg_result(stu_name text, month3_avg numeric, month4_avg numeric)
),
sum_data as (select * from crosstab($$select stu_name, extract (month from eval_day) eval_month,round(sum(eval_result),2) sum_resultfrom  evaluationsgroup by stu_name , extract (month from eval_day) order by 1,2$$,'select distinct  extract (month from eval_day) eval_month from evaluations order by 1') as avg_result(stu_name text, month3_sum numeric, month4_sum numeric)
)
select a.stu_name,a.month3_avg, a.month4_avg, month3_sum, month4_sum
from avg_data as a join sum_data as b
on a.stu_name = b.stu_name

执行结果:

stu_name month3_avg month4_avg month3_sum month4_sum
peter 6.60 33.00
smith 8.33 5.50 25.00 11.00

漂亮,与我们预想的一致,只是代码稍微有点冗长,但又有一定相似性。未来我们继续进行优化。

总结

本文通过 tablefunc实现交叉表展示聚合函数的值,并利用with展示多个聚合函数的值,突破了 tablefunc功能限制。

PostgreSQL 实现交叉表查询(2)相关推荐

  1. 创建交叉表_质性数据分析软件NVivo教程:交叉表查询

    交叉表查询提供了一种快速的方法来检查案例和人口统计变量之间的编码分布.例如,您可以使用交叉表查询来: 检查受访者回答某特定主题或问题的频率. 比较不同人口群体对主题的看法. 在运行交叉表查询之前,您需 ...

  2. java动态交叉表,SqlServer如何生成动态交叉表查询

    为了说明问题,我们用SqlServer自带的事例数据库(Northwind)来进行验证,所有的例子请放到Northwind中运行,我可能会省略Use语句,所引用的表,都是Northwind中的,下面我 ...

  3. ireport交叉报表 crosstab排序_质性数据分析软件NVivo教程:交叉表查询

    交叉表查询提供了一种快速的方法来检查案例和人口统计变量之间的编码分布.例如,您可以使用交叉表查询来: 检查受访者回答某特定主题或问题的频率. 比较不同人口群体对主题的看法. 在运行交叉表查询之前,您需 ...

  4. 交叉表 mysql_mysql交叉表查询解决方案整理

    交叉表是一种常用的分类汇总查询.使用交叉表查询,可以显示表中某个字段的汇总值,并将它们分组,其中一组列在数据表的左侧,另一组列在数据表的上部.行和列的交叉处可以对数据进行多种汇总计算,如:求和.平均值 ...

  5. 在MySQL中实现交叉表查询2(动态交叉表)

    在MySQL中实现交叉表查询2(动态交叉表) 交叉表分为静态交叉表和动态交叉表.其中静态交叉表中的列是固定的,因此相对容易实现:而动态交叉表中的列需要动态生成. 一.静态交叉表的实现 参见上一篇文章: ...

  6. Mysql的交叉表查询

    最近由于找工作,所以在恶补PHP和Mysql方面的东西,发现还是学习的不够.这几天看到关于mysql的交叉表查询的内容,根据自己的理解简单的尝试了下. 由于MonsterHunter World较火, ...

  7. 在MySQL中实现交叉表查询1(静态交叉表)

    在MySQL中实现交叉表查询1(静态交叉表) 一.什么是交叉表 交叉表查询是将来源于某个表中的字段进行分组,一组列在交叉表左侧,一组列在交叉表上部,并在交叉表行与列交叉处显示表中某个字段的各种计算值. ...

  8. 5.7.1 使用向导创建交叉表查询

    示例ACCESS数据库下载链接: https://download.csdn.net/download/ngbshzhn/20979935 使用交叉表查询计算和重构数据,可以简化数据分析,交叉表查询计 ...

  9. 【交叉表查询】行列转换的魅力

    本文主要是讲一下行列转换,也就是大家经常讲的交叉表查询. 行列转换在实际的应用中非常的实用,可以大大的减少工作量. 很多时候,在Excel中处理数据时,我们需要统计每个月的销量或者需要填写每个月的销量 ...

最新文章

  1. 数据访问与sql语句的管理(一)
  2. 简述ajax的优缺点
  3. 虚拟化与云计算(一)之 Lab1 使用 Hadoop Mapreduce 进行数据处理
  4. vim、gvim在windows下中文乱码的终极解决方案
  5. 文件服务器有病毒,服务器共享文件会被病毒加密吗
  6. 海量网络存储系统原理与设计(三)
  7. oracle有没有mysql if_Oracle中没有 if exists(...)
  8. java base64 转图片不现实_Base64.decodeBase64将base64转图片的问题
  9. JAVA使用反射的方法,参数是数组怎么办?
  10. Activiti实战. 1.3Activiti的特点
  11. 戴尔笔记本重装系统硬盘加密怎么解除
  12. 【时间纷飞】死人,死人
  13. [rock]Life ’s A Struggle -宋岳庭(转)
  14. 计算营业额python_告诉你怎么用Python进行企业营运分析!盈利这么多?
  15. 装修细节注意问题 装修细节有哪些
  16. 健康生活 多用肥皂少用洗涤剂
  17. 整理-如何在solution manager里面删除未传到生产的请求
  18. STO,跨公司采购,第三方销售,跨公司销售
  19. Python舔狗日记学习手册 【没想到还有第二期】
  20. AVR mega48 ISP下载及熔丝位修正

热门文章

  1. 贵州高速 | 山地变出“平原”新感觉
  2. 《CTF攻防世界web题》之我什么都不会(1)
  3. iOS开发--UIWebView
  4. 【工业现场】核心工段机器代人,维视智造助力环保行业智能升级
  5. 树莓派56/100 - 用Pico连接蜂鸣器演奏音乐,用来纪念儿时玩的超级玛丽游戏
  6. 使用华为云会议的总结【华为云至简致远】
  7. 横河川仪压力变送器调零_日本横河川仪EJA变送器零点调整方法!
  8. 如何免费下载word文档
  9. LDF explorer使用问题记录
  10. 转载:CPU, DSP, GPU, FPGA对比