茫茫網海中的冷日 - 對這文章發表回應
茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1670354 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
HoiHoiSan_00021.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

對這文章發表回應

發表限制: 非會員 可以發表

發表者: 冷日 發表時間: 2022/10/25 4:14:21

08.使用 INSERT INTO … SELECT 輸入不重複資料

前言

這幾個月遇到一個需求:在某一個 Stored Procedure 需要把 Temp Table 資料寫入某一個資料表,但 ID重複的資料不寫入。寫入的語法為 INSERT SELECT,而重點在過濾資料的部分。一開始想到的作法是 NOT EXISTS 語法,但因為不理解,擔心有效能上的問題,於是在 Stack Overflow 上找到相關文章,發現其實有多種寫法,也有專家分析其優劣。


介紹

舉個簡單的例子,我們有資料表 A 與 B:
Table_A

IdName
1AA
2BB
3CC

Table_B

IdName
1PP

需求是將資料表A 的資料 放入資料表B,但不放入 ID 重複的資料。如果不過濾資料直接放入,我們的語法大概會長這樣


INSERT INTO TABLE_B
(Id, Name)
SELECT ta.Id,
ta.Name
FROM TABLE_A ta

而我們會有三種方法
NOT EXISTS


INSERT INTO TABLE_B (Id, name)
SELECT ta.Id,
ta.Name
FROM TABLE_A ta
WHERE NOT EXISTS ( SELECT Id
FROM TABLE_B tb
WHERE tb.Id = t1.Id )

NOT IN


INSERT INTO TABLE_B (idIdName)
SELECT ta.Id,
ta.Name
FROM TABLE_A ta
WHERE ta.Id NOT IN (SELECT Id
FROM TABLE_B)

LEFT JOIN/IS NULL


INSERT INTO TABLE_B  (Id, Name)
SELECT ta.Id,
ta.Name
FROM TABLE_A ta
LEFT JOIN TABLE_B tb ON t2.id = t1.id
WHERE t2.Id IS NULL

一看到 LEFT JOIN + IS NULL,就覺得這方法好像不錯,但其實專家們不推薦使用。若欄位皆為 非NULL 的情況下 NOT EXISTS 與 NOT IN 執行效率接近,且比起 LEFT JOIN + IS NULL 快上3倍。
而如果有複合鍵 NOT EXISTS 會特別有效 (可以點選參考資料2,看一下詳細比較)。

看看 Stack Overflow 找到解決方法時,別忘了看一下專家解釋,如果直接複製貼上可能會出糗;如果有回答不錯的,別忘了幫忙投票一下 :D


參考資料

  1. Stack Overflow: https://stackoverflow.com/questions/2513174/avoid-duplicates-in-insert-into-select-query-in-sql-server
  2. NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL: SQL Server - EXPLAIN EXTENDED https://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/

偷偷分享一下自己的資料


原文出處:
08.使用 INSERT INTO … SELECT 輸入不重複資料 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天
內容圖示
url email imgsrc image code quote
樣本
bold italic underline linethrough   












 [詳情...]
validation picture

注意事項:
預覽不需輸入認證碼,僅真正發送文章時才會檢查驗證碼。
認證碼有效期10分鐘,若輸入資料超過10分鐘,請您備份內容後,重新整理本頁並貼回您的內容,再輸入驗證碼送出。

選項

Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|