加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

如何实现postgresql两张表数据的对比更新

(2013-05-02 15:00:28)
标签:

postgresql

sql

分类: 计算机世界
由于软件升级,系统新建的表与原表中有部分数据有出入,需要进行对比更新。
旧表信息如下(表名:cffex):
         mdate        |  mopen  |  mhigh  |  mlow   | mclose  |   vol   |   opid  |   sp    | scale
---------------------+---------+---------+---------+---------+---------+----------+---------+-------
 2010-05-26 15:14:00 | 2839.60 | 2839.60 | 2838.40 | 2839.60 |  951.00 | 15219.00 | 2839.07 |  0.54
 2010-06-22 15:14:00 | 2798.80 | 2799.00 | 2797.60 | 2797.60 |  927.00 | 19828.00 | 2798.18 |  0.45
 2010-09-20 15:14:00 | 2873.60 | 2873.60 | 2872.80 | 2873.00 |  989.00 | 23457.00 | 2873.24 |  0.54
 2010-10-18 15:14:00 | 3329.40 | 3330.60 | 3329.00 | 3329.40 |  760.00 | 25731.00 | 3329.72 |  0.52
 2011-01-21 14:59:00 | 2985.60 | 2985.60 | 2985.20 | 2985.40 |  126.00 |  1018.00 | 2985.43 |  0.37
 2011-04-20 15:14:00 | 3313.80 | 3316.60 | 3313.20 | 3316.00 | 1112.00 | 29702.00 | 3314.52 |  0.58

新表信息如下(表名:if_min1):
   mdate    |  mtime   |  mopen  |  mhigh  |  mlow   | mclose  |   vol   |   opid   |   sp    | scale
------------+----------+---------+---------+---------+---------+---------+----------+---------+--------------------
 2010-05-26 | 15:14:00 | 2839.60 | 2839.60 | 2838.40 | 2839.60 |  951.00 | 15219.00 | 2839.07 | -1920.00
 2010-06-22 | 15:14:00 | 2798.80 | 2799.00 | 2797.60 | 2797.60 |  927.00 | 19828.00 | 2798.18 | -816.00
 2010-09-20 | 15:14:00 | 2873.60 | 2873.60 | 2872.80 | 2873.00 |  989.00 | 23457.00 | 2873.24 | -2625.00
 2010-10-18 | 15:14:00 | 3329.40 | 3330.60 | 3329.00 | 3329.40 |  759.00 | 25731.00 | 3329.80 |  1407.00
 2011-01-21 | 14:59:00 | 2985.60 | 2985.60 | 2985.20 | 2985.40 |  126.00 |  1018.00 | 2985.43 | -2520.00
 2011-04-20 | 15:14:00 | 3313.80 | 3316.60 | 3313.20 | 3316.00 | 1112.00 | 29702.00 | 3314.52 | -0.01

其中旧表中的mdate字段被分拆为新表的mdate,mtime两个字段,其余内容不变,但scale字段的数据有部分出错,所以需要根据旧表将其进行修正。SQL语句如下
--------------------------------------------------------------------------------------------------
UPDATE if_min1 SET scale=cffex.scale
               FROM cffex
               WHERE to_timestamp(CONCAT(if_min1.mdate,' ',if_min1.mtime),
                     'YYYY-MM-DD HH24:MI:SS')::timestamp without time zone = cffex.mdate 
                     AND (if_min1.scale<0 OR if_min1.scale >1);
--------------------------------------------------------------------------------------------------
说明:
在WHERE子句中限定条件,利用CONCAT函数对新表的mdate,mtime进行合并,然后使用to_timestamp函数进行日期型数据转化,仅取大于0且小于1的数据;

结果:
   mdate    |  mtime   |  mopen  |  mhigh  |  mlow   | mclose  |   vol   |   opid   |   sp    |  scale
------------+----------+---------+---------+---------+---------+---------+----------+---------+----------
 2010-05-26 | 15:14:00 | 2839.60 | 2839.60 | 2838.40 | 2839.60 |  951.00 | 15219.00 | 2839.07 |  0.54
 2010-06-22 | 15:14:00 | 2798.80 | 2799.00 | 2797.60 | 2797.60 |  927.00 | 19828.00 | 2798.18 |  0.45
 2010-09-20 | 15:14:00 | 2873.60 | 2873.60 | 2872.80 | 2873.00 |  989.00 | 23457.00 | 2873.24 |  0.54
 2010-10-18 | 15:14:00 | 3329.40 | 3330.60 | 3329.00 | 3329.40 |  759.00 | 25731.00 | 3329.80 |  0.52
 2011-01-21 | 14:59:00 | 2985.60 | 2985.60 | 2985.20 | 2985.40 |  126.00 |  1018.00 | 2985.43 |  0.37
 2011-04-20 | 15:14:00 | 3313.80 | 3316.60 | 3313.20 | 3316.00 | 1112.00 | 29702.00 | 3314.52 |  0.58

附录:UPDATE命令说明
名字
UPDATE -- 更新表中的数据行

语法
UPDATE [ ONLY ] table [ [ AS ] alias ]
SET { column = { expression | DEFAULT }
( column [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...]
[ FROM fromlist ]
[ WHERE condition | WHERE CURRENT OF cursor_name ]
[ RETURNING * | output_expression [ AS output_name ] [, ...] ]

描述
UPDATE更新满足指定的条件的数据行。
默认的情况下,UPDATE会更新指定的表和它的所有子表中的数据。如果不想更新指定的表的子表中的数据,使用ONLY子句。
如果想引用其它的表中的信息,可以使用子查询或FROM子句。
RETURNING子句在每更新一个数据行时,以被更新的数据行为基础计算出一个或多个表达式的值返回给用户,这些表达式可以引用被删除数据的表的列,也可以引用FROM子句中出现的表的列。如果表达式引用了被更新的列,使用该列的新值来计算表达式的值。RETURNING子句的语法类似于SELECT语句的输出列表。
执行命令的用户必须在被更新的表上有UPDATE权限,同时要在expressions或condition引用的表上有SELECT权限(或者是超级用户)。
参数
table
被更新的表的名字(可以用模式修饰)。
alias
表的别名,一旦为表取了一个别名,语句剩下的部分只能用别名来引用这个表,表的原来的名字将不可见。例如,假设有UPDATE foo AS f,则UPDATE语句剩下的部分只能用f来引用表 foo 。
column
被更新的列的名字。如果列是复合类型,可以引用列的某个域,如果列是数组类型,可以引用列的某个元素。例如,UPDATE tab SET tab.col = 1。
expression
赋给被更新的列的表达式。它可以引用被更新的列的原来的值,也可以引用表中的其它列。
DEFAULT
将列设成它的默认值(如果列没有被明确地指定默认值,则它的默认值是空值)。
fromlist
表表达式的列表。它的语法类似于 SELECT语句的FROM子句中表表达式的列表,可以为表指定别名。不要在fromlist中引用被删除数据的表,除非这个表需要同自身进行连接操作。fromlist 中的表表达式的列可以被expression和condition引用。
condition
返回值为boolean类型的表达式。
cursor_name
WHERE CURRENT OF子句中使用的游标的名字。这个游标的查询必须是被更新的表上的简单查询(没有连接,没有聚集函数)。WHERE CURRENT OF子句与WHERE子句不能同时出现。将更新游标最近一次访问的数据行。
output_expression
在每个数据行被更新以后将被计算的表达式。表达式的值将被作为UPDATE命令的结果返回。它可以引用被更新的表和FROM子句中的表的任何列。* 表示返回所有的列。
output_name
返回的列的名字。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有