MySQL对数据的基本操作三:UPDATE语句
注:(1)內連接可以不使用ON或者WHERE;外連接必須使用ON子句,否則會報錯!!!
? ? ? ?(2)UPDATE確定數據源頭(或者說,UPDATE子句確定“待操作數據集”),WHERE子句:對“待操作數據集”做二次篩選。
? ? ? ?(3)案例4:這個例子說明,UPDATE語句可以同時修改多張表。。。
? ? ? ?(4)子查詢不能在UPDATE語句中使用的原因:首先,在UPDATE中使用子查詢,這會是相關子查詢,效率很低;然后,MySQL不允許對要更改或要刪除記錄的數據表做子查詢(很顯然,動腦子想一想也明白了);
目錄
一:UPDATE語句簡介
二:案例:不涉及表連接? 的案例(這部分不難)
三:案例:涉及表連接
一:UPDATE語句簡介
●?UPDATE子句,選擇要修改的表;UPDATE子句只執行一次;
●?IGNORE關鍵字可寫可不寫,作用是在寫入數據的時候,如果遇到沖突就直接忽略。
●?WHERE子句:篩選要修改的記錄;
●?ORDER BY子句的應用場合:把篩選出的記錄進行排序。比如,當修改記錄的主鍵的時候,給主鍵值都加1的時候,就需要把數據降序排列,這樣才不會在修改主鍵的時候發生唯一性沖突;(自然如果給主鍵值都減1,就需要把數據升序排列了);
● LIMIT子句:這兒的LIMIT子句只能寫一個參數;
下面的執行順序:UPDATE子句→WHERE子句→ORDER BY子句→LIMIT子句→SET子句;
二:案例:不涉及表連接? 的案例(這部分不難)
案例1:把每個員工的編號和上司的編號+1,用ORDER?BY子句完成;
這個例子很簡單,不涉及多表查詢;
UPDATE t_emp SET empno=empno+1,mgr=mgr+1 ORDER BY empno DESC;……………………………………………………
案例2:把月收入排在前三名的員工,底薪減100元,用LIMIT子句完成
注意,LIMIT子句的用法。
這個例子很簡單,不涉及多表查詢;
UPDATE t_emp SET sal=sal-100 ORDER BY sal+IFNULL(comm,0) DESC LIMIT 3;……………………………………………………
案例3:把10部門中,工齡超過20年的員工,底薪增加200元,WHERE子句
這個例子很簡單,不涉及多表查詢;
UPDATE t_emp SET sal=sal+200 WHERE deptno=10 AND FLOOR(DATEDIFF(NOW(),hiredate)/365)>=20;三:案例:涉及表連接
案例4:把ALLEN調往RESEARCH部門,職務調整為ANALYST;
這個案例中,涉及到了多張表,RESEARCH部門的編號不知道;
最直接的思路:使用子查詢。
UPDATE t_emp e SET job="ANALYST",deptno=(SELECT d.deptno FROM t_dept d WHERE d.dname="RESEARCH") WHERE e.ename="ALLEN";但是上面的做法中,子查詢是相關子查詢,如果需要修改的不止ALLEN一人,那么【SELECT d.deptno FROM t_dept d WHERE d.dname="RESEARCH"】將會執行很多次。。。
涉及多張表的時候,需要引入表連接:
下面的兩種表連接都是內連接的語法:內連接的,其中包括使用ON子句,和使用ON子句。
利用表連接的方式實現:這種騷操作。。。(這兒非常重要!!!!!,是核心!!!)
UPDATE t_emp e JOIN t_dept d SET e.deptno=d.deptno,e.job="ANALYST",d.loc="成都" WHERE e.ename="ALLEN" AND d.dname="RESEARCH";分析:執行過程是,現將倆表做笛卡爾積(因為沒有使用ON子句啦)從t_emp表中篩選出e.name="ALLEN"這條記錄,從t_dept表中篩選出d.dname="RESEARCH"這條記錄,其實,這所謂的兩條記錄在【笛卡爾積】中是在一條記錄上的;此時,已經分別在兩個表中各獲得了一條記錄,然后分別在獲取的這兩條記錄上執行執行【SET e.deptno=d.deptno,e.job="ANALYST",d.loc="成都"】。然后,對此條記錄的操作就能影響到原表上。
這個表連接的例子其實并不難,很簡單,多想一下表連接的那個結果集,,,,,
同時,這個例子說明,UPDATE語句可以同時修改多張表。。。
……………………………………………………
案例5:把底薪低于公司平均底薪的員工,底薪增加150元;
【公司的平均底薪】和【誰的底薪低于公司的平均底薪】不知道;
我的解決方案:還是這種很騷的操作,,,
UPDATE t_emp e1 JOIN (SELECT AVG(sal) aa FROM t_emp) e2 SET e1.sal=e1.sal+150 WHERE e1.sal<e2.aa;注:這個例子和【案例4】結合后,可以發現,這種表連接的騷操作,可以應用于多條記錄的情況。
即,重復下【案例4】中的話,這些在笛卡爾積上挑選出的記錄,對這些記錄的更改可以影響到原表上。
通過這個例子,更加說明,UPDATE子句是指執行一次的。
標準做法:和我的做法類似,只是這兒將條件放在了ON子句中,我的做法是將條件放在了WHERE子句中。
UPDATE t_emp e1 JOIN (SELECT AVG(sal) aa FROM t_emp) e2 ON e1.sal<e2.aa SET e1.sal=e1.sal+150;……………………………………………………
UPDATE語句的表連接的第三種方式:外連接的語法,外連接的時候,條件只能寫在ON子句中,,,而且ON子句不能少!!!!!
案例6:把沒有部門的員工,或者SALES部門低于2000底薪的員工,都調往20部門。
涉及到多張表,需要表連接;張三沒有部門,連接時需要保留,所以需要外連接;
第一種錯誤方案:
UPDATE t_emp e LEFT JOIN (SELECT deptno FROM t_dept WHERE dname="SALES") dd ON e.deptno=NULL OR (e.sal<=2000 AND e.deptno=dd.deptno) SET e.deptno=20;可以發現,實際效果出錯了如BLACK的部門也沒改成20了。首先,判斷字段是不是空,需要IS?NULL?而不是=NULL;
動動腦子:在左連接的時候,左邊的記錄都會被保留下來!!!!!!!!!!所以,這兒的結果是錯誤的,deptno全變成20了。。。
第二種錯誤方案:錯誤原因,經過多次測試,發現左連接和右連接必須要有ON子句,否則會報錯。這個需要后續確定,并在外連接的那篇博客中標記一下。
UPDATE t_emp e LEFT JOIN (SELECT deptno FROM t_dept WHERE dname="SALES") dd SET e.deptno=20 WHERE e.deptno IS NULL OR (e.sal<=2000 AND e.deptno=dd.deptno);標準做法:這個例子很典型,調理清晰,好好想想,,,
這兒,UPDATE確定數據源頭(或者說,UPDATE子句確定“待操作數據集”),WHERE子句:對“待操作數據集”做二次篩選。
UPDATE t_emp e LEFT JOIN t_dept d ON e.deptno=d.deptno SET e.deptno=20 WHERE e.deptno IS NULL OR (d.dname="SALES" AND e.sal<2000);?
?
?
?
總結
以上是生活随笔為你收集整理的MySQL对数据的基本操作三:UPDATE语句的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle数据透明加密,oracle数
- 下一篇: 干货丨看金仓数据库如何支持透明加密!