教你如何用SQLite 實現if not exist 類似功能的操作
需要實現:
if not exists(select * from ErrorConfig where Type='RetryWaitSeconds') begin insert into ErrorConfig(Type,Value1) values('RetryWaitSeconds','3') end
只能用:
insert into ErrorConfig(Type,Value1) select 'RetryWaitSeconds','3' where not exists(select * from ErrorConfig where Type='RetryWaitSeconds')
因為 SQLite 中不支援SP
在用sqlite3熟悉SQL的時候遇到了一個百思不得其解的問題,也沒有在google上找到答案。雖然最後用“迂迴”的方式碰巧解決了這個問題,但暫時不清楚原理是什麼,目前精力有限,所以暫時記錄下來,有待繼續研究。
資料庫是這樣的:
CREATE TABLE book ( id integer primary key, title text, unique(title) ); CREATE TABLE checkout_item ( member_id integer, book_id integer, movie_id integer, unique(member_id, book_id, movie_id) on conflict replace, unique(book_id), unique(movie_id) ); CREATE TABLE member ( id integer primary key, name text, unique(name) ); CREATE TABLE movie ( id integer primary key, title text, unique(title) );
該資料庫包含了4個表:book, movie, member, checkout_item。其中,checkout_item用於儲存member對book和movie的借閱記錄,屬於關係表。
SQL語句(SQL1)如下:
SELECT * FROM member WHERE id NOT IN(SELECT member_id FROM checkout_item);
得到了想要的結果。
這看起來與上一個是類似的,於是我理所當然地執行了如下的SQL語句(SQL2):
SELECT * FROM book WHERE id NOT IN(SELECT book_id FROM checkout_item);
可是——執行結果沒有找到任何記錄! 我看不出SQL2與SQL1這兩條語句有什麼差別,難道是book表的問題?於是把NOT去掉,執行了如下查詢語句:
SELECT * FROM book WHERE id IN(SELECT book_id FROM checkout_item);
正確返回了被借出的book,其數量小於book表裡的總行數,也就是說確實是有book沒有借出的。
接著google(此處省略沒有營養的字),沒找到解決方案。可是,為什麼member可以,book就不可以呢?它們之前有什麼不同?仔細觀察,發現checkout_item裡的book_id和movie_id都加了一個unique,而member_id則沒有。也許是這個原因?不用id了,換title試試:
SELECT * FROM book WHERE title NOT IN( SELECT title FROM book WHERE id IN( SELECT book_id FROM checkout_item));
確實很迂迴,但至少work了。。。
事實是,我自己的解決方案只不過是碰巧work,這個問題產生跟unique沒有關係。邱俊濤的解釋是,“SELECT book_id FROM checkout_item”的結果中含有null值,導致NOT也返回null。當一個member只借了movie而沒有借book時,產生的checkout_item中book_id就是空的。
解決方案是,在選擇checkout_item裡的book_id時,把值為null的book_id去掉:
SELECT * FROM book WHERE id NOT IN(SELECT book_id FROM checkout_item WHERE book_id IS NOT NULL);
我在解決這個問題的時候方向是不對的,應該像除錯程式一樣,去檢查中間結果。比如,執行如下語句,結果會包含空行:
SELECT book_id FROM checkout_item
而執行下列語句,結果不會包含空行:
SELECT member_id FROM checkout_item
這才是SQL1與SQL2兩條語句執行過程中的差別。根據這個差別去google,更容易找到答案。當然了,沒有NULL概念也是我“百思不得其解”的原因。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901823/viewspace-2851807/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PostgreSQL類似OracleMERGE功能的實現SQLOracle
- 教你如何用 MongoDB 實現評論榜功能MongoDB
- 用 hyperf websocket 實現,類似 qq 單機登入功能Web
- 碼教授教你一些系統功能實現的操作
- lakeFS:實現類似於Git或事件溯源ES的物件儲存功能Git事件物件
- 教你如何用vbs實現微信自動傳送訊息功能
- 教你如何用smokeping實現釘釘告警
- 教你如何用 Java 實現非同步呼叫Java非同步
- MySQL 06 mysql 如何實現類似 oracle 的 merge intoMySqlOracle
- 用 golang 去實現類似 swoole 的 websocket 服務 ?GolangWeb
- 如何實現類似 lodash 的 get 與 merge 函式函式
- flutter實現類似優惠券樣式Flutter
- Flutter 實現類似TabPicker省市區選擇Flutter
- 用RecyclerView實現類似支付寶應用圖示拖拽排序以及增刪管理的功能View排序
- 100多行程式碼實現js或者jquery版的類似juejin的預覽圖片功能行程JSjQuery
- 教你如何用 Lua 操作檔案中的資料
- 採用 SwiftNIO 實現一個類似 Express 的 Web 框架SwiftExpressWeb框架
- 在dotnet core實現類似crontab的定時任務
- Laravel 小技巧 - 讓路由實現類似 Model::query 的效果Laravel路由
- 深度解析:在 React 中實現類似 Vue 的 KeepAlive 元件ReactVue元件
- Blazor如何實現類似於微信的Tab切換?Blazor
- 使用PasteSpider實現類似Jenkins的功能,讓你的2G伺服器也可以飛起ASTIDEJenkins伺服器
- 開源一個自用的Android事件分發中心庫,實現類似系統廣播功能。Android事件
- 類似淘票票 選座功能(svg)SVG
- 使用KubernetesIngress來實現類似Istio條件路由路由
- H5開發類似rpx實現方法H5
- 用Java 19實現類似Go併發 - mccueJavaGo
- 在鴻蒙中實現類似瀑布流效果鴻蒙
- 教你使用SQLite VacuumSQLite
- 萬字教你如何用 Python 實現線性規劃Python
- WinForm使用DataGridView實現類似Excel表格的查詢替換ORMViewExcel
- 01 . Go之從零實現Web框架(類似Gin)GoWeb框架
- idou老師教你學Istio:如何用 Istio 實現速率限制
- 教你如何用WPF實現文字粒子閃爍動畫效果動畫
- 原生JS實現類似《掘金》網站的圖片檢視器JS網站
- 使用.net standard實現不同內網埠的互通(類似花生殼)內網
- [Swift]SpriteKit實現類似畫素鳥的小遊戲 - Crashy PlaneSwift遊戲
- mysql中substring_index類似split分組功能MySqlIndex