----start
我估計,只要是知道SQL語句的人都會用UPDATE語句,可是大部分人不知道UPDATE語句有兩種寫法,首先,考慮下面的情況:
CREATE TABLE STUDENT<br />(<br /> ID INT,---學號<br /> NAME VARCHAR(20) NOT NULL,---姓名<br /> BIRTHDAY DATE---生日<br /> primary key(ID)<br />); </p><p>INSERT INTO STUDENT (ID,NAME,BIRTHDAY) VALUES<br />(1,'張三','1991-1-1'),<br />(2,'李四','1991-1-1'),<br />(3,'王五','1990-1-1');
假設讓你更新一下張三的生日,很簡單,我們可以這麼寫:
UPDATE STUDENT SET BIRTHDAY='1991-1-5' WHERE NAME='張三';
除此之外,我們還可以這麼寫:
UPDATE<br />(<br /> SELECT * FROM STUDENT WHERE NAME='張三'<br />)<br />SET BIRTHDAY='1991-1-5'
就上面這個例子而言,通常我們不會使用第二種寫法,因為這種寫法可讀性不如第一種寫法好,下面我們舉一個用第一種方法辦不到得例子,可是用第二種方法卻非常簡單(這是一個生產環境實際的例子,通常用在銀行中,關於表定義,我做了簡化),考慮如下情況:
CREATE TABLE TRANSACTION<br />(<br /> CUSTOMERID VARCHAR(10),---顧客號<br /> SEQ INT NOT NULL,---流水號(每個顧客從1開始)<br /> PROCESSDATE DATE,---處理日<br /> AMOUNT DECIMAL(16,4)---金額<br />);
對於上面表的流水號(SEQ)欄位,每個顧客從1開始,而且它的順序,其實就是處理日(PROCESSDATE)排序後的順序。細心的朋友可能已經發現,這樣設計明顯違反了表的第二範式,造成資料冗餘。確實是這樣的,為什麼要這樣設計呢?真實的原因我也不知道,只能問該系統的設計者。我猜測可能的原因是,系統的設計者將銀行用的紙質報表直接轉化為了資料庫中的表,紙質報表有流水號(SEQ)欄位是可以的,因為紙質報表我們無法排序,也不可能讓會計去數每個顧客到底發生了多少交易,但是在資料庫的表中,該欄位則完全沒有必要,因為我們可以通過對處理日(PROCESSDATE)排序後產生該結果。相反,如果設定流水號(SEQ)欄位,就有可能因為這樣那樣的問題導致流水號(SEQ)和處理日(PROCESSDATE)排序結果不一致,這時候就要求我們更新流水號(SEQ),那麼,我們該怎麼更新呢?這個問題很好解決,通常我們會將查詢結果排序後,更新其中的每一條記錄。這樣做是可以的,但是有點笨,我們能不能用一條語句來更新呢?答案是可以的,如下:
UPDATE<br />(<br /> SELECT<br /> TT.*,<br /> ROW_NUMBER() OVER() AS RN<br /> FROM<br /> TRANSACTION AS TT WHERE CUSTOMERID=...<br />)<br />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