DB2 UPDATE 语句

----start

我估计,只要是知道SQL语句的人都会用UPDATE语句,可是大部分人不知道UPDATE语句有两种写法,首先,考虑下面的情况:

CREATE TABLE STUDENT ( ID INT,---学号 NAME VARCHAR(20) NOT NULL,---姓名 BIRTHDAY DATE---生日 primary key(ID) ); INSERT INTO STUDENT (ID,NAME,BIRTHDAY) VALUES (1,'张三','1991-1-1'), (2,'李四','1991-1-1'), (3,'王五','1990-1-1'); 

假设让你更新一下张三的生日,很简单,我们可以这么写:

UPDATE STUDENT SET BIRTHDAY='1991-1-5' WHERE NAME='张三'; 

除此之外,我们还可以这么写:

UPDATE ( SELECT * FROM STUDENT WHERE NAME='张三' ) SET BIRTHDAY='1991-1-5' 

就上面这个例子而言,通常我们不会使用第二种写法,因为这种写法可读性不如第一种写法好,下面我们举一个用第一种方法办不到得例子,可是用第二种方法却非常简单(这是一个生产环境实际的例子,通常用在银行中,关于表定义,我做了简化),考虑如下情况:

CREATE TABLE TRANSACTION ( CUSTOMERID VARCHAR(10),---顾客号 SEQ INT NOT NULL,---流水号(每个顾客从1开始) PROCESSDATE DATE,---处理日 AMOUNT DECIMAL(16,4)---金额 ); 

对于上面表的流水号(SEQ)字段,每个顾客从1开始,而且它的顺序,其实就是处理日(PROCESSDATE)排序后的顺序。细心的朋友可能已经发现,这样设计明显违反了表的第二范式,造成数据冗余。确实是这样的,为什么要这样设计呢?真实的原因我也不知道,只能问该系统的设计者。我猜测可能的原因是,系统的设计者将银行用的纸质报表直接转化为了数据库中的表,纸质报表有流水号(SEQ)字段是可以的,因为纸质报表我们无法排序,也不可能让会计去数每个顾客到底发生了多少交易,但是在数据库的表中,该字段则完全没有必要,因为我们可以通过对处理日(PROCESSDATE)排序后产生该结果。相反,如果设置流水号(SEQ)字段,就有可能因为这样那样的问题导致流水号(SEQ)和处理日(PROCESSDATE)排序结果不一致,这时候就要求我们更新流水号(SEQ),那么,我们该怎么更新呢?这个问题很好解决,通常我们会将查询结果排序后,更新其中的每一条记录。这样做是可以的,但是有点笨,我们能不能用一条语句来更新呢?答案是可以的,如下:

UPDATE ( SELECT TT.*, ROW_NUMBER() OVER() AS RN FROM TRANSACTION AS TT WHERE CUSTOMERID=... ) SET SEQ=RN 

怎么样,是不是很简单。通过以上的分析,你可能对UPDATE语句的两种方法有一定的了解。如果你对上面语句的ROW_NUMBER() OVER()还不熟悉,请参见:DB2 在线分析处理(OLAP函数的使用)

---更多参见:DB2 SQL 精萃

----声明:转载请注明出处。

----last updated on 2010.1.9

----written by ShangBo on 2010.1.9

----end

 

你可能感兴趣的:(DB2)