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.字符类型 字符数据类型用于声明包含字母.数字数据的字段 ...
随机推荐
- Golang 包了解以及程序的执行
Golang 包了解以及程序的执行 引言 Go 语言是使用包来组织源代码的,包(package)是多个 Go 源码的集合,是一种高级的代码复用方案.Go 语言中为我们提供了很多内置包,如 fmt.o ...
- 分库分表之后分布式如何保证ID全局唯一性
分库分表之后分布式如何保证ID全局唯一性 韩师学子--小倪 2018-07-21 23:35:38 8139 收藏 3分类专栏: Mysql版权 分库分 ...
- XML文档约束有哪几种?有什么区别?
XML DTD(功能有限) XML Schema (功能强大) Schema本身是XML的,可以被XML解析器解析(这也是从DTD上发展schema的根本目的),Schema支持命名空间,Schema ...
- 你如何理解 Spring Boot 中的 Starters?
Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成 Spring 及其他技术,而不需要到处找示例代码和依赖包.如你想使用 Spring JPA 访问数据库,只 ...
- js的json序列化和反序列化
(1)序列化 即js中的Object转化为字符串 1.使用toJSONString var last=obj.toJSONString(); //将JSON对象转化为JSON字符 2.使用string ...
- Myql 中的事务回滚机制概述 ?
事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个 不可分割的工作单位,事务回滚是指将该事务已经完成的对数据库的更新操作撤 销.要同时修改数据库中两个不同表时,如果它们不是一个事务 ...
- 转:C++11常用新特性快速一览
转载至:https://blog.csdn.net/jiange_zh/article/details/79356417 1.nullptr nullptr 出现的目的是为了替代 NULL. 在某种意 ...
- nginx搭建简单直播服务器
1.下载模块(nginx-rtmp-module) 1 cd /data/nginx 2 yum install git3 git clone https://github.com/arut/ngin ...
- mybatis-02-mapper生成器插件使用
sb_mybatis <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...
- 介绍一项让 React 可以与 Vue 抗衡的技术
好吧,我承认我是标题党.React 明明如日中天,把它与 Vue 倒过来,给 Vue 加点东西或可与 React 抗衡.不过,这两年 Vue 干的正是这事,不断加东西,不断优化,按它现有发展速度超越 ...