瀏覽標籤:

SQL

[MSSQL] SQL Server 的一些眉眉角角 part.2

小知識

    1. 交易中資料表會持續鎖定至交易結束或是連線結束
    2. 最外層的交易 ROLLBACK,內層就算 COMMIT 依然會復原變更
    3. 巢狀交易過程中的資料表都會鎖定直到交易結束,外層交易 COMMIT 內層交易卻沒有 COMMIT 資料表會被鎖定不會釋放
    4. 交易前加上 SET XACT_ABORT ON 可防止過程中發生錯誤沒有 ROLLBACK 造成鎖表的問題

閱讀更多

[MSSQL] SQL Server 的一些眉眉角角 part.1

目前工作 Database 方面主要都在使用 SQL Server,寫了近兩年的 Stored Procedure 也遇到了許多的問題,在這裡簡單筆記一下。

  1. 暫存資料表小知識
    * ### 建立的暫存資料表,可從 tempdb.暫存資料表 找到。
    * # 建立的暫存資料表只有該連線可以取用;## 則是全部連線均可使用。
    * 連線結束時皆會自動刪除,若程式中有 Connection Pool 來管理連線則不會立刻刪除。
    * 父層 Stored Procedure 建立的暫存資料表子層也可以使用;子層 Stored Procedure 建立的暫存資料表父層也可以使用
  2. 若開啟交易 (Transaction) 但無提交異動 (Commit) 會發生資料表鎖死 (Table Lock) 的問題,切記要提交異動 (Commit)。
  3. 使用主鍵來 UPDATE 為資料鎖 (Row Lock),若使用其他條件則有可能會升級成資料頁鎖(Page Lock) 或資料表鎖 (Table Lock)。
  4. 交易 (Transaction) 具有復原機制 (RollBack),但實際上資料表中的資料已經被異動且鎖定的關係所以無法取得,可利用 WITH(NOLOCK) 來取得被鎖定的髒資料。
  5. 未開啟交易時使用 CURSORUPDATE FROM 若超過五千筆時可能會造成鎖定與死結,可使用 ROW_NUMBER() 排序資料塞入暫存資料表並使用 WHILE 來一筆一筆更新資料避開鎖定,速度雖慢但能減少鎖死。
  6. 高負載情況下使用 UPDATE OUTPUT 的方法來取得資料更新前後的狀態,可減少 SELECT 次數提高效率。
  7. 高負載情況下可能會將隔離層級拉高到 Serializable,這時使用交易會發生相同資料表 SELECT UPDATE 中的 Shared Lock 與 Exclusive Lock 撞車造成 DeadLock,可在 SELECT 加上 WITH(UPDLOCK) 來減少此問題。

[Docker][Linux] SQL Server 安裝筆記

環境:Window 7

  1. 安裝 Docker Toolbox
  2. 新增 Volume

 

  1. 建立容器

 

  1. 更新時區

 

參考資料:

  1. Linux Docker 運行 MSSQL
  2. 快速入門: 使用 Docker 執行 SQL Server 2017 容器映像
  3. 在Linux上使用环境变量配置SQL Server设置

[MySQL][LeetCode][Medium] 177. Nth Highest Salary

心得

這題非常有趣,題目要求寫一預存程式輸入N並取出排名第N名的薪水為多少,這題與178. Rank Scores差不多,所以可以直接套用。

題目

Write a SQL query to get the nth highest salary from the Employee table.

For example, given the above Employee table, the nth highest salary where n = 2 is 200. If there is no nth highest salary, then the query should return null.

答案

  1. 這題我是拿178. Rank Scores的解法直接套上去取N

     
  2. 這解法是由高至低排序了所有的薪水,再用LIMIT來獲取Nth(因為LIMIT是從0開始所以N必須先減一),非常易懂的解法。

     

參考:

  1. [MySQL][LeetCode][Medium] 178. Rank Scores

[MySQL][LeetCode][Medium] 184. Department Highest Salary

心得

題目要求找出每個部門薪水最高的員工,若同部門最高薪水有複數則一起顯示,這題我在JOIN部門清單的時候先去把各部門最高薪資數字先撈了出來,這樣在關聯兩張表的時候就可以直接搜尋員工薪水是否等於最高薪資。

問題

The Employee table holds all employees. Every employee has an Id, a salary, and there is also a column for the department Id.

The Department table holds all departments of the company.

Write a SQL query to find employees who have the highest salary in each of the departments. For the above tables, Max has the highest salary in the IT department and Henry has the highest salary in the Sales department.

答案

  1. JOIN部門清單的時候先去把各部門最高薪資數字先撈了出來
  2. (2017/01/16) 寫 185. Department Top Three Salaries 時後發現的方法

[MySQL][LeetCode][Medium] 178. Rank Scores

心得

題目要求找出成績排名,如果分數相同的話則相同名次,MySQL不像MSSQL有ROW_NUMBER()可以用,只好用個變數來存了。

問題

Write a SQL query to rank scores. If there is a tie between two scores, both should have the same ranking. Note that after a tie, the next ranking number should be the next consecutive integer value. In other words, there should be no “holes” between ranks.

For example, given the above Scores table, your query should generate the following report (order by highest score):

答案

 

[MySQL][LeetCode][Easy] 196. Delete Duplicate Emails

心得

題目要求刪除同樣Email的資料,在DELETE的條件WHERE裡面不能包含異動的表(Person),所以這裡再包了一層SELECT來排除編譯錯誤的問題,而這層必須給予別名(強制)否則會編譯錯誤。

問題

Write a SQL query to delete all duplicate email entries in a table named Person, keeping only unique emails based on its smallest Id.

For example, after running your query, the above Person table should have the following rows:

答案

 

[MySQL][LeetCode][Easy] 197. Rising Temperature

心得

題目要求找出溫度比前一天高的資料,這裡用了DATE_SUBTO_DAYS兩種方式來解答。

題目

Given a Weather table, write a SQL query to find all dates’ Ids with higher temperature compared to its previous (yesterday’s) dates.

For example, return the following Ids for the above Weather table:

答案

  1. Sub Query
  2. Join
  3. TO_DAYS

     

參考:

  1. DATE_ADD() 與 DATE_SUB() 日期的加法與減法
  2. Mysql日期和時間函數不求人