簡體   English   中英

根據另一個表中的條件更新一個表中的列 SQL 服務器 (Transact-SQL)

[英]Updating a column in one table based on criteria in another table SQL Server (Transact-SQL)

我正在嘗試根據員工的薪水更新我的 Employee 表中的GradeID字段(等級是工資帶)。

我需要參考的詳細信息存在於不同的成績表中。

我嘗試使用以下內容更新此內容,但這不起作用:

UPDATE e
SET e.GradeID = g.gID
FROM Employee e
INNER JOIN Grade g
    ON e.GradeID=g.gID
WHERE e.salary BETWEEN coalesce(g.minSalary, 0) AND coalesce(g.maxSalary, 9999999999)

我收到以下回復,但沒有更改任何字段:

(9 rows affected)

Completion time: ###

您的查詢不起作用,因為您在已經匹配的鍵值上加入了EmployeeGrade

我會非常謹慎地建議按照您在 WHERE 子句中指定的條件加入表格。 (非常小心,因為簡單地將條件從 WHERE 子句移動到 FROM 子句中連接的 ON 部分通常不是一件容易的事。在某些情況下,它可能會顯着影響含義和行為。但在這種情況會很好,因為它實際上是你的意圖。)

此外,我會避免使用BETWEEN... AND...表達式並更喜歡單獨的比較( A >= 3 AND A <= 5而不是A BETWEEN 3 AND 5 )。 但這只是個人喜好。

更重要的是,我肯定會避免在任何情況下使用函數(如COALESCE ),以便 SQL Server 可以更好地利用索引(如果可用)。

UPDATE e
SET GradeID = g.gID
FROM Employee e
INNER JOIN Grade g
    ON ((g.minSalary IS NULL OR e.salary >= g.minSalary) AND
        (g.maxSalary IS NULL OR e.salary <= g.maxSalary))

編輯:

關於索引的使用, Gordon Linoff在對我的回答的評論中向我指出,查詢條件中的OR運算符與函數一樣具有破壞性。

我在網上做了一個簡短的研究,在 Cybertec 的網站上找到了 Laurenz Albe 的文章“Avoiding OR for better query performance” 它是為 PostgreSQL 編寫的,但是我認為如果它不適用於 SQL 服務器,它至少可以為專門針對 Z9778840A0100CB30C982876741B0B5A 服務器的調查提供一個起點。 我會繼續尋找 SQL 服務器的具體信息。

作為避免OR並回退到功能替代的查詢結構的一個可能示例,我將我的第一個查詢重寫為:

UPDATE E
SET GradeID = x.gID
FROM Employee e
INNER JOIN (
  SELECT e.eID, g.gID
  FROM Employee e
  INNER JOIN Grade g
    ON g.minSalary IS NULL AND
       g.maxSalary IS NULL
  UNION ALL
  SELECT e.eID, g.gID
  FROM Employee e
  INNER JOIN Grade g
    ON e.salary >= g.minSalary AND
       g.maxSalary IS NULL
  UNION ALL
  SELECT e.eID, g.gID
  FROM Employee e
  INNER JOIN Grade g
    ON g.minSalary IS NULL AND
       e.salary <= g.maxSalary
  UNION ALL
  SELECT e.eID, g.gID
  FROM Employee e
  INNER JOIN Grade g
    ON e.salary >= g.minSalary AND
       e.salary <= g.maxSalary
) x ON x.eID = e.eID;

我僅出於演示目的而包含此替代查詢。 我沒有分析性能,因為我當然沒有匹配的填充數據庫。 因此,我會將任何所需的測量或查詢計划調查留給您。 也可能結果是,四個單獨的 UPDATE 查詢可能同樣好(而且內存占用更少)。

小費:

請注意,閱讀代碼的頻率要高於編寫代碼的頻率。 因此,始終創建可讀和可維護的代碼很重要。 對於 SQL 尤其如此,即使它的格式很好,通常也被認為很難閱讀和理解。 任何優化都應徹底記錄。 創建查詢時,請始終制作盡可能簡單明了的第一個版本。 優化后,您可以在查詢的文檔/注釋中包含該簡單的原始查詢,這將有助於在未來的代碼分析、維護和/或優化任務中理解查詢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM