• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            SQL使用記錄

            問題:Update字段來自子查詢或者來自其他表字段

            Update 語句

            Update 語句用于修改表中的數(shù)據(jù)。

            語法:

            UPDATE 表名稱 SET 列名稱 = 新值 WHERE 列名稱 = 某值
            SQL update select語句
            最常用的update語法是:
            UPDATE <table_name> SET <column_name1> = <value>, SET <column_name2> = <value>
            如果我的更新值Value是從一條select語句拿出來,而且有很多列的話,用這種語法就很麻煩
            第一,要select出來放在臨時變量上,有很多個哦
            第二,再將變量進(jìn)行賦值。
            列多起來非常麻煩,能不能像Insert那樣,把整個Select語句的結(jié)果進(jìn)行插入呢?就好象下面
            insert into table1 (c1, c2, c3) (select v1, v2, v3 from table2)
             
            答案是可以的,具體的語法如下:
            UPDATE <table_name> <alias>
            SET (<column_name>,<column_name> ) = (
            SELECT (<column_name>, <column_name>)
            FROM <table_name>
            WHERE <alias.column_name> = <alias.column_name>)
            WHERE <column_name> <condition> <value>;
             
            下面是這樣一個例子:
            兩個表a、b,想使b中的memo字段值等于a表中對應(yīng)id的name值 
            表a:id, name 
            1 王 
            2 李 
            3 張 
            表b:id,ClientName   
                        1 
            (MS SQL Server)語句:update b   set   ClientName    = a.name    from a,b    where a.id = b.id  
            (Oralce)語句:update b   set   (ClientName)    =   (SELECT name FROM a WHERE b.id = a.id)
            update set from 語句格式
            當(dāng)where和set都需要關(guān)聯(lián)一個表進(jìn)行查詢時,整個update執(zhí)行時,就需要對被關(guān)聯(lián)的表進(jìn)行兩次掃描,顯然效率比較低。
            對于這種情況,Sybase和SQL SERVER的解決辦法是使用UPDATE...SET...FROM...WHERE...的語法,實際上就是從源表獲取更新數(shù)據(jù)。
             
            在 SQL 中,表連接(left join、right join、inner join 等)常常用于 select 語句,其實在 SQL 語法中,這些連接也是可以用于 update 和 delete 語句的,在這些語句中使用 join 還常常得到事半功倍的效果。
            Update T_OrderForm SET T_OrderForm.SellerID =B.L_TUserID
            FROM T_OrderForm A LEFT JOIN T_ProductInfo   B ON B.L_ID=A.ProductID
            用來同步兩個表的數(shù)據(jù)!
             
            Oralce和DB2都支持的語法:
            UPDATE A SET (A1, A2, A3) = (SELECT B1, B2, B3 FROM B WHERE A.ID = B.ID)
            MS SQL Server不支持這樣的語法,相對應(yīng)的寫法為:
            UPDATE A  SET A1 = B1, A2 = B2, A3 = B3  FROM A LEFT JOIN B ON A.ID = B.ID
            個人感覺MS SQL Server的Update語法功能更為強(qiáng)大。MS SQL SERVER的寫法:
            UPDATE A SET A1 = B1, A2 = B2, A3 = B3 FROM A, B WHERE A.ID = B.ID
            OracleDB2中的寫法就比較麻煩了,如下:
            UPDATE A SET (A1, A2, A3) = (SELECT B1, B2, B3 FROM B WHERE A.ID = B.ID)
            WHERE ID IN (SELECT B.ID FROM B WHERE A.ID = B.ID)


            但對于MySql以上卻不行

            Single-table語法:

            UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
                SET col_name1=expr1 [, col_name2=expr2 ...]
                [WHERE where_definition]
                [ORDER BY ...]
                [LIMIT row_count]

            Multiple-table語法:

            UPDATE [LOW_PRIORITY] [IGNORE] table_references
                SET col_name1=expr1 [, col_name2=expr2 ...]
                [WHERE where_definition]

            UPDATE語法可以用新值更新原有表行中的各列。SET子句指示要修改哪些列和要給予哪些值。WHERE子句指定應(yīng)更新哪些行。如果沒有WHERE子句,則更新所有的行。如果指定了ORDER BY子句,則按照被指定的順序?qū)π羞M(jìn)行更新。LIMIT子句用于給定一個限值,限制可以被更新的行的數(shù)目。

             

            如果您在一個表達(dá)式中通過tbl_name訪問一列,則UPDATE使用列中的當(dāng)前值。例如,以下語句把年齡列設(shè)置為比當(dāng)前值多一:

            UPDATE persondata SET age=age+1;

            UPDATE賦值被從左到右評估。例如,以下語句對年齡列加倍,然后再進(jìn)行增加:

            UPDATE persondata SET age=age*2, age=age+1;

            如果您把一列設(shè)置為其當(dāng)前含有的值,則MySQL會注意到這一點(diǎn),但不會更新。

            update表的某些字段為null

            update person set number=null,name=null;

            如果您把被已定義為NOT NULL的列更新為NULL,則該列被設(shè)置到與列類型對應(yīng)的默認(rèn)值,并且累加警告數(shù)。對于數(shù)字類型,默認(rèn)值為0;對于字符串類型,默認(rèn)值為空字符串('');對于日期和時間類型,默認(rèn)值為“zero”值。

             

            多個表的UPDATE操作

            UPDATE items,month SET items.price=month.price WHERE items.id=month.id;

            以上的例子顯示出了使用逗號操作符的內(nèi)部聯(lián)合,但是multiple-table UPDATE語句可以使用在SELECT語句中允許的任何類型的聯(lián)合,比如LEFT JOIN,但是您不能把ORDER BYLIMITmultiple-table UPDATE同時使用。

            MYSQL聯(lián)合多表更新和刪除
            多表更新
            在 MySQL 3.23 中,你可以使用 LIMIT # 來確保只有給定的記錄行數(shù)目被更改。 

            如果一個 ORDER BY 子句被使用(從 MySQL 4.0.0 開始支持),記錄行將以指定的次序被更新。這實際上只有連同 LIMIT 一起才有用。 

            從 MySQL 4.0.4 開始,你也可以執(zhí)行一個包含多個表的 UPDATE 的操作: 

            UPDATE items,month SET items.price=month.price
            WHERE items.id=month.id;

            注意:多表 UPDATE 不可以使用 ORDER BY 或 LIMIT。 


            多表刪除
            第一個多表刪除格式從 MySQL 4.0.0 開始被支持。第二個多表刪除格式從 MySQL 4.0.2 開始被支持。 

            僅僅在 FROM 或 USING 子句 之前 列出的表中的匹配記錄行被刪除。效果就是,你要以從多個表中同時刪除記錄行,并且同樣可以有其它的表用于檢索。 

            在表名后的 .* 僅僅是為了兼容 Access: 

            DELETE t1,t2 FROM t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id   or    DELETE FROM t1,t2 USING t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id

            在上面的情況下,我們僅僅從 t1 和 t2 表中刪除匹配的記錄行。 

            如果一個 ORDER BY 子句被使用(從 MySQL 4.0.0 開始支持), 記錄行將以指定的次序刪除。這實際上只有連同 LIMIT 一起才有用。示例如下: 

            DELETE FROM somelog  WHERE user = 'jcole'  ORDER BY timestamp LIMIT 1

            這將刪除匹配 WHERE 子句的,并且最早被插入(通過 timestamp 來確定)的記錄行。 

            DELETE 語句的LIMIT rows 選項是 MySQL 特有的,它告訴服務(wù)器在控制權(quán)被返回到客戶端之前可被刪除的最大記錄行數(shù)目。這可以用來確保一個特定的 DELETE 命令不會占用太長的時間。你可以簡單地重復(fù)使用 DELETE 命令,直到被影響的記錄行數(shù)目小于 LIMIT 值。 

            從 MySQL 4.0 開始,在 DELETE 語句中可以指定多個表,用以從一個表中刪除依賴于多表中的特殊情況的記錄行。然而,在一個多表刪除中,不能使用 ORDER BY 或 LIMIT。
            假設(shè)有兩個表,tab1,tab2,分別有產(chǎn)品名稱和產(chǎn)品價格,現(xiàn)在我想用tab2的價格替換tab1的價格,我寫的語句是Update tab1 set tab1.產(chǎn)品價格=tab2.產(chǎn)品價格 where tab1.產(chǎn)品名稱=tab2.產(chǎn)品名稱 
            結(jié)果出現(xiàn)錯誤,提示為:列前綴 'tab2' 與查詢中所用的表名或別名不匹配。請問應(yīng)該怎樣寫,

            SQL語句是不支持多表同時更新的。 

            應(yīng)該這樣寫 

            update tab1 set tab1.產(chǎn)品價格 = (select tab2.產(chǎn)品價格 from tab2 where tab2.產(chǎn)品名稱 = tab1.產(chǎn)品名稱) where tabl1.產(chǎn)品名稱 in (select tab2.產(chǎn)品名稱 from tab2) 


            后面的where tab1.產(chǎn)品名稱 in (select tab2.產(chǎn)品名稱 from tab2) 這句保證了如果tab1的產(chǎn)品在tab2沒有記錄時不會出錯。


            在 開發(fā)中,數(shù)據(jù)庫來回?fù)Q,而有些關(guān)鍵性的語法又各不相同,這是一件讓開發(fā)人員很頭痛的事情.本文總結(jié)了Update語句更新多表時在SQL Server,Oracle,MySQL三種數(shù)據(jù)庫中的用法.我也試了SQLite數(shù)據(jù)庫,都沒成功,不知是不支持多表更新還是咋的. 

            在本例中: 

            我們要用表gdqlpj中的gqdltks,bztks字段數(shù)據(jù)去更新landleveldata中的同字段名的數(shù)據(jù),條件是當(dāng)landleveldata 中的GEO_Code字段值與gdqlpj中的lxqdm字段值相等時進(jìn)行更新. 

            SQL Server語法: 
            UPDATE 
                      { 
                       table_name WITH ( < table_hint_limited > [ ...n ] ) 
                       | view_name 
                       | rowset_function_limited 
                      } 
                      SET 
                      { column_name = { expression | DEFAULT | NULL } 
                      | @variable = expression 
                      | @variable = column = expression } [ ,...n ] 

                  { { [ FROM { < table_source > } [ ,...n ] ] 

                      [ WHERE 
                          < search_condition > ] } 
                      | 
                      [ WHERE CURRENT OF 
                      { { [ GLOBAL ] cursor_name } | cursor_variable_name } 
                      ] } 
                      [ OPTION ( < query_hint > [ ,...n ] ) ] 

            SQL Server示例: 
            update a 
            set a.gqdltks=b.gqdltks,a.bztks=b.bztks 
            from landleveldata a,gdqlpj b 
            where a.GEO_Code=b.lxqdm 

            Oracle語法: 
            UPDATE    updatedtable 
                  SET (col_name1[,col_name2...])= 
            (SELECT    col_name1,[,col_name2...]   
            FROM    srctable [WHERE where_definition]) 

            Oracel 示例: 
            update landleveldata a 
            set (a.gqdltks, a.bztks)= 
            (select b.gqdltks, b.bztks    from gdqlpj b 
                where a.GEO_Code=b.lxqdm) 

            MySQL語法: 
            UPDATE table_references 
                  SET col_name1=expr1 [, col_name2=expr2 ...] 
                  [WHERE where_definition] 

            MySQL 示例: 
            update landleveldata a, gdqlpj b 
            set a.gqdltks= b.gqdltks, 
            a.bztks= b.bztks 
                where a.GEO_Code=b.lxqdm

            MySQL SELECT同時UPDATE同一張表
            MySQL不允許SELECT FROM后面指向用作UPDATE的表,有時候讓人糾結(jié)。當(dāng)然,有比創(chuàng)建無休止的臨時表更好的辦法。本文解釋如何UPDATE一張表,同時在查詢子句中使用SELECT.

            問題描述

            假設(shè)我要UPDATE的表跟查詢子句是同一張表,這樣做有許多種原因,例如用統(tǒng)計數(shù)據(jù)更新表的字段(此時需要用group子句返回統(tǒng)計值),從某一條記錄的字段update另一條記錄,而不必使用非標(biāo)準(zhǔn)的語句,等等。舉個例子:
            1. create table apples(variety char(10) primary key, price int);  
            2.   
            3. insert into apples values('fuji', 5), ('gala', 6);  
            4.   
            5. update apples  
            6.     set price = (select price from apples where variety = 'gala')  
            7.     where variety = 'fuji';  

            錯誤提示是:ERROR 1093 (HY000): You can't specify target table 'apples' for update in FROM clause. MySQL手冊UPDATE documentation這下面有說明 : “Currently, you cannot update a table and select from the same table in a subquery.”
            在這個例子中,要解決問題也十分簡單,但有時候不得不通過查詢子句來update目標(biāo)。好在我們有辦法。

            解決辦法

            既然MySQL是通過臨時表來實現(xiàn)FROM子句里面的嵌套查詢,那么把嵌套查詢裝進(jìn)另外一個嵌套查詢里,可使FROM子句查詢和保存都是在臨時表里進(jìn)行,然后間接地在外圍查詢被引用。下面的語句是正確的:
            1. update apples  
            2.    set price = (  
            3.       select price from (  
            4.          select * from apples  
            5.       ) as x  
            6.       where variety = 'gala')  
            7.    where variety = 'fuji';  

            如果你想了解更多其中的機(jī)制,請閱讀MySQL Internals Manual相關(guān)章節(jié)。

            沒有解決的問題

            一個常見的問題是,IN()子句優(yōu)化廢品,被重寫成相關(guān)的嵌套查詢,有時(往往?)造成性能低下。把嵌套查詢裝進(jìn)另外一個嵌套查詢里并不能阻止它重寫成相關(guān)嵌套,除非我下狠招。這種情況下,最好用JOIN重構(gòu)查詢(rewrite such a query as a join)。

            另一個沒解決的問題是臨時表被引用多次。“裝進(jìn)嵌套查詢”的技巧無法解決這些問題,因為它們在編譯時被創(chuàng)建,而上面討論的update問題是在運(yùn)行時。(譯者注:個人認(rèn)為跟文章討論的主題沒幾毛錢關(guān)系)

            轉(zhuǎn)載請注明出處 http://blog.csdn.net/afeiqiang/article/details/8589535

            原文地址 http://www.xaprb.com/blog/2006/06/23/how-to-select-from-an-update-target-in-mysql/

            posted on 2015-03-17 15:43 Daywei 閱讀(768) 評論(0)  編輯 收藏 引用 所屬分類: DB

            <2013年4月>
            31123456
            78910111213
            14151617181920
            21222324252627
            2829301234
            567891011

            導(dǎo)航

            統(tǒng)計

            常用鏈接

            留言簿

            隨筆分類

            隨筆檔案

            文章檔案

            牛人博客

            搜索

            積分與排名

            最新評論

            閱讀排行榜

            久久热这里只有精品在线观看| 日韩精品久久久久久久电影蜜臀| 青草影院天堂男人久久| 久久综合综合久久97色| 久久久久一本毛久久久| 久久夜色精品国产噜噜亚洲AV | 国产精品乱码久久久久久软件| 久久精品卫校国产小美女| 精品久久久久久综合日本| 久久九九久精品国产| 欧美成a人片免费看久久| 久久精品国产亚洲AV嫖农村妇女 | 国产精品无码久久久久| 2019久久久高清456| 国产成人久久精品二区三区| 中文字幕热久久久久久久| 国产精品嫩草影院久久| 久久精品国产99久久无毒不卡| 日韩电影久久久被窝网| 精品国产福利久久久| 久久久久高潮综合影院| 久久青青国产| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 久久精品国产网红主播| 亚洲一区精品伊人久久伊人| 嫩草影院久久99| 99久久99久久久精品齐齐| 精品一二三区久久aaa片| 狠狠色综合久久久久尤物| 麻豆精品久久精品色综合| 狠狠色丁香久久综合五月| 亚洲AV日韩精品久久久久久久| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 国内精品久久久久久久久| 久久久青草久久久青草| 2022年国产精品久久久久| 91精品国产综合久久精品| 97精品伊人久久大香线蕉app | 亚洲国产视频久久| 久久亚洲AV无码精品色午夜| 无码任你躁久久久久久老妇|