postgreSQL使用sql归一化数据表的某列,以及出现“字段 ‘xxx’ 必须出现在 GROUP BY 子句中或者在聚合函数中”错误的可能原因之一
前言:
归一化(区别于标准化)一般是指,把数据变换到(0,1)之间的小数。主要是为了方便数据处理,或者把有量纲表达式变成无量纲表达式,便于不同单位或量级的指标能够进行比较和加权。
不过还是有很多人使用时将归一化(normalization)和标准化(standardization)两个概念混淆,在这里我们就不过多讨论了。这里的归一化主要指的是这个常用的公式:
x' = (x - X_min) / (X_max - X_min)
最近使用openlayers添加heatmap图层的时候,查看官方文档发现,发现热力图的权重数据(weight)需要范围在0-1的数据。而我使用的数据是省会城市所对应省份的县及县级以上城市数量,所以就需要对数据进行归一化处理。

postgreSQL中的min和max函数可以求出最小值和最大值,所以就决定直接在数据库中处理。
先是准备工作,将原始数据建立一个只有省会城市名(name),省内县及县级以上城市数量(value)和geom字段的查询,名叫process_t,便于归一化。

归一化的sql语句,一开始我是这样写的,其中process_t就是上面处理过的查询:
select name,geom,
process_t.value,
(value-min(process_t.value))/(max(process_t.value)-min(process_t.value))
from process_t
然而运行的时候出现了这么一个错误。但如果去掉min和max函数,或者去掉其他字段,这个错误就不会出现。

所以,这是由于max和min函数输出的值只有一条记录(最大值或最小值),但其他字段(name等)却拥有多条记录,这不能在一个查询中同时存在。因此,类似value-min(process_t.value),这样的语句就更行不通的。


那么如何解决这个问题呢?
sql支持类似向量一样的运算,一个字段的多条记录与一个固定值进行运算是可以得到结果的,例如 value-1 就不会出现问题。

所以我们要保证的就是,sql语句中,与其他字段同时出现的不应该是一个带有聚合(统计)功能的函数(例如min,max,avg,stddev等),而是一个通过这些函数产生的固定值。这样就不会出现统计结果只有一条记录而其他字段有多条记录产生的冲突了。
例如:
select name,geom,
process_t.value,
(select max(process_t.value) from process_t) as max,
(select min(process_t.value) from process_t) as min
from process_t
其中的,(select max(process_t.value) from process_t) as max,
(select min(process_t.value) from process_t) as min
这两句话与直接使用max(process_t.value)或min(process_t.value)函数不同,它是将最大值和最小值的查询结果作为一个固定值写入新的查询之中,这样会让max和min字段的每条记录都有一个固定的值。

然后根据这个查询结果,通过公式进行归一化运算即可!!
当然,因为直接用(select max(process_t.value) from process_t)查询出来的结果可以作为一个固定值使用,所以也可以写成类似于’ value-1 ‘那样的语句,不产生新的字段,直接用原始数据归一化,例如:
select name,geom,
process_t.value,
(process_t.value - (select min(process_t.value) from process_t))*1.0/((select max(process_t.value) from process_t)-(select min(process_t.value) from process_t))
from process_t

不难看到,这样做确实可以实现归一化。但这样写出来sql语句可读性实在是太差,所以还是先产生一个带有max和min字段的子查询,再进行归一化,这样会比较合理(在不考虑时空效率的前提下)。
最后,还有一点需要注意,归一化过程涉及整数相除,与C/C++,Java的除法类似的是,为了让结果保留为浮点数,sql语句中一定需要对整数类型进行强制类型转换或者像图中一样直接乘一个浮点数(1.0)
postgreSQL使用sql归一化数据表的某列,以及出现“字段 ‘xxx’ 必须出现在 GROUP BY 子句中或者在聚合函数中”错误的可能原因之一的更多相关文章
- sql复制数据表和表结构
SQL复制数据表 (select * into 与 insert into) select * into 目标表名 from 源表名 insert into 目标表名(fld1, fld2) sele ...
- [SQL]SQL Server数据表的基础知识与增查删改
SQL Server数据表的基础知识与增查删改 由张晨辉(学生) 于19天 前发表 | 阅读94次 一.常用数据类型 .整型:bigint.int.smallint.tinyint .小数:decim ...
- 【SQL 代码】SQL复制数据表及表结构
select * into 目标表名 from 源表名 from 源表名 以上两句都是将'源表'的数据插入到'目标表',但两句又有区别的: 第一句(select into from)要求目标表不存在, ...
- SQL复制数据表及表结构
select * into 目标表名 from 源表名 insert into 目标表名(fld1, fld2) select fld1, 5 from 源表名 以上两句都是将'源表'的数据插入到'目 ...
- SqlServer创建数据表描述及列描述信息
SqlServer创建数据表描述及列描述信息 Intro Q: 为什么要创建描述信息? A: 鼠标悬停在对应表和列上时,会出现描述信息,可以提高工作的效率,借助工具我们根据数据表可以生成Model,可 ...
- 第二百七十七节,MySQL数据库-数据表、以及列的增删改查
MySQL数据库-数据表.以及列的增删改查 1.创建一个表 CREATE(创建) TABLE(表) ENGINE(引擎) ENGINE=INNODB(引擎)还有很多类引擎,这里只是简单的提一下INNO ...
- 一.oracle的SQL中group by使用的情况(与聚合函数的关系)
SELECT r.industry_1,r.industry_2,r.agent_id,r.agent_name,COUNT(DISTINCT r.customer_name_a)数据总量,COUNT ...
- C#向sql server数据表添加数据源代码
HoverTree解决方案 学习C#.NET,Sql Server,WinForm等的解决方案. 本文链接http://hovertree.com/h/bjaf/0jteg8cv.htm 使用的技术. ...
- sql总结-----数据表操作
数据表概述 表示一种最常见的组织数据的方式,一张表一般有多个列(即多个字段). oracle提供了多种内置的列的数据类型,常用的有以下五种: 1.字符类型 字符数据类型用于声明包含字母.数字数据的字段 ...
随机推荐
- C++设计模式 - 访问器模式(Visitor)
行为变化模式 在组件的构建过程中,组件行为的变化经常导致组件本身剧烈的变化."行为变化" 模式将组件的行为和组件本身进行解耦,从而支持组件行为的变化,实现两者之间的松耦合. 典型模 ...
- KCP协议:从TCP到UDP家族QUIC/KCP/ENET
行文前先安利下<再深谈TCP/IP三步握手&四步挥手原理及衍生问题-长文解剖IP >.<再谈UDP协议-浅入理解深度记忆> KCP协议科普 KCP是一个快速可靠协议,能 ...
- 什么是 inode ?
一般来说,面试不会问 inode .但是 inode 是一个重要概念,是理解 Unix/Linux 文件系统和硬盘储存的基础.理解inode,要从文件储存说起.文件储存在硬盘上,硬盘的最小存储单位叫做 ...
- Shiro Session放到Redis中常遇到的问题
Shiro会话管理:https://shiro.apache.org/session-management.html#SessionManagement-CustomSessionIDs Redis主 ...
- Java并发机制(6)--阻塞队列
Java并发编程:阻塞队列整理自:博客园-海子-http://www.cnblogs.com/dolphin0520/p/3933404.html 1.什么是阻塞队列 除了同步容器(Hashtable ...
- 学习RabbitMQ(二)
MOM(message oriented middleware) 消息中间件(是在消息的传递过程中保存消息的容器,消息中间件再将消息从它的源中继到它的目标时,充当中间人的作用,队列的主要目的是提供路由 ...
- 树莓派系统安装(ubuntu版本)无需屏幕
0.前提 所需物品:一个手机.一台电脑.一个树莓派.一张tf卡和一个读卡器.所需软件:Win32DiskImager.putty还需要ubuntu系统镜像源.这些我都放在百度网盘上了链接:https: ...
- About HTML
HTML 简介 HTML 历史 最初的 HTMl 是由 CERN负责制定的,后来转交给 IETF. 在 1990-1995 年期间, HTML 经历了许多次的版本修改与扩充: 1995 年的时候 HT ...
- ps基础总结
1.复制图层:首先选中移动工具(V),鼠标右键选中需要复制的图层(快捷方式:上面勾选自动选择),接着一只手按住Alt键,另一只手点击鼠标左键(不松开),往左往右移动即可.若是对多个图层起作用,就可将需 ...
- HTML表格CSS美化
效果展示 style.css html{ width: 100%; height: 100%; overflow: hidden;}body{ width: 100%; height: 100%; f ...