2010-03-20 51 views
6

我有一個表中定義了員工關係的表。 即如何從包含自引用外鍵的表中刪除所有數據

EmpID Name SeniorId 
----------------------- 
1   A  NULL 
2   B  1 
3   C  1 
4   D  3 

等等...

其中高級ID是外鍵,其主鍵表一樣的是refrence列EMPID 我想清楚從這個表中的所有行,而不刪除任何約束。我怎樣才能做到這一點?

刪除需要像執行該 4,3,2,1

我怎樣才能做到這一點

編輯:

的Jhonny的答案是爲我工作,但它的答案更有效率。

+0

這是很清楚的的Jhonny的是最有效和最好的答案,我只留礦爲充當一個提醒,有時候我沒有,因爲我覺得我聰明。 – 2010-03-20 13:41:18

+0

@Larry。因爲它會先更新所有行然後刪除它們,因此應該效率更低。而不是直接刪除。哪個操作更高效,循環或查詢?請讓我清楚。我不知道這兩個 – 2010-03-20 13:43:57

+0

基於集合的命令的想法可能會比運行在一個循環內衆多基於集合的命令,即使在後一種情況下每個命令的影響較少的行得更快。實際結果可能會有所不同,例如,表格索引或參考級別數量;你必須測試以確保你有真正的最佳狀況。但是Jhonny的「看起來」更好,而且肯定會更清晰,更容易實施。 – 2010-03-20 13:49:28

回答

13

如果我失去了一些東西,我不知道,但也許你可以試試這個。

UPDATE employee SET SeniorID = NULL 
DELETE FROM employee 
+0

他自己。把事情簡單化! :-) – PapillonUK 2014-04-10 23:31:35

1

在循環中,運行一個命令,刪除所有具有未引用EmpID的行,直到剩下零行。有多種方式來編寫內DELETE命令:

DELETE FROM employee WHERE EmpID NOT IN (SELECT SeniorID FROM employee) 

DELETE FROM employee e1 WHERE NOT EXISTS 
    (SELECT * FROM employee e2 WHERE e2.SeniorID = e.EmpID 

,並使用連接可能是第三個,但我不熟悉的SQL Server語法。

+0

@Larry:Thx回答。我認爲這個答案只考慮兩個級別的高級。 PLZ檢查在DVK的回答我的評論更多細節 – 2010-03-20 13:41:40

+0

這就是爲什麼你必須做一個循環,直到沒有剩下的行。但Jhonny的回答更好。 – 2010-03-20 13:43:43

1

一種解決方法是通過將「高級」關係拆分爲單獨的表來規範化。爲了通用性,使第二個表「empID1 | empID2 | relationship_type」。除了這個,你需要在循環中做到這一點。一種方法是做到這一點:

declare @count int 
select @count=count(1) from table 
while (@count > 0) 
BEGIN 
    delete employee WHERE NOT EXISTS 
     (select 1 from employee 'e_senior' 
     where employee.EmpID=e_senior.SeniorID) 
    select @count=count(1) from table 
END 
+0

組織結構未定義,因此我們無法正常化。即使1名高級也可以有其高級等。即A的高級B,B的高級C,C的高級d等 – 2010-03-20 13:30:29

+0

我不知道我理解爲什麼不通過反正我加了第二種方法 – DVK 2010-03-20 13:31:47

2

試試這個

DELETE FROM employee; 
3

如果表是非常大的(數以百萬計基數),而無需登錄的DELETE交易,丟棄約束和TRUNCATEing並重新創建約束是遠遠最有效的方法。另外,如果在其他表中有外鍵(並且在這個特定的表設計中它看起來如此),那麼在所有情況下也必須首先刪除這些行。

規範化沒有提及遞歸/層次/樹關係,所以我相信在你回覆DVK建議將它分解成它自己的表的時候,它是一個紅色的鯡魚 - 它當然可以對此表進行垂直分區並考慮是否可以利用這一點來獲得我在下面列出的任何其他好處。正如DVK所暗示的,在這個特別的設計中,我經常看到一個單獨的鏈接表來記錄自我關係和其他類型的關係。這有很多好處:

  • 有很多很多上下,而不是多到一個(不常見,但可能很有用)
  • 跟蹤不同類型的直接關係 - 經理,顧問,助理,工資審批,費用審批,技術報告,來 - 與關係和關係型表,而不是在員工表中的新列的行
  • 按部就班地進行,包括活動指標和有效的改變在時間上一致的方式層次結構(包括離職員工層次的歷史)關係行上的日期 - 這隻有在將關係歸一化到其自己的表中時纔是完全可能的
  • SeniorID中的NULL(實際上在任一ID上) - 這是避免錯誤邏輯的明顯優勢,但NULL通常會出現在視圖中,無論如何您必須將關聯表左連接到
  • 更好的專用索引策略 - 而不是添加SeniorID到你已經擁有員工的特定索引(尤其是關係類型的數量增長)

當然,與這種關係相關的信息越多,表明關係本身值得一張表(即它是在這個詞的真正意義上的「關係」在關係數據庫中使用 - 相關數據被存儲在一個關係或表 - 與主鍵),從而爲關係的正常形態可能會強烈地表明,關係表在employee表中創建而不是簡單的外鍵關係。

好處還包括其簡單的刪除場景:

DELETE FROM EmployeeRelationships; 
DELETE FROM Employee; 

您會在這裏對SO注意到一個引人注目的等效性接受的答案,因爲,你的情況,沒有高層關係的員工有一個NULL - 所以在那個答案海報首先設置NULL爲消除關係,然後刪除員工。

根據約束(EmpployeeRelationships通常能夠被TRUNCATEd,因爲它的主鍵通常是一個組合鍵而不是任何其他表中的外鍵),可能有適當的TRUNCATE用法。

相關問題