目錄
1. 第十二課 查詢的執行順序
1.1 知識點
討論在瞭解所有查詢語句的基礎上,如何將查詢語句進行完整的組合。整體書序結構如下所示:
完成SELECT查詢
SELECT DISTINCT column, AGG_FUNC(column_or_expression), …
FROM mytable
JOIN another_table
ON mytable.column = another_table.column
WHERE constraint_expression
GROUP BY column
HAVING constraint_expression
ORDER BY column ASC/DESC
LIMIT count OFFSET COUNT;
即:每個查詢都從查找數據庫中需要的數據開始,然後將這些數據過濾成可以儘快處理和理解的內容。因爲查詢的每個部分都是按順序執行的,所以瞭解執行順序非常重要,可以知道哪些結果可以快速訪問。下面對執行順序依次進行講解:
(1)FROM和JOIN
首先執行該FROM子句和後續步驟JOIN以確定正在查詢的數據的總工作集。這包括此子句中的子查詢,並且可以導致在引擎蓋下創建臨時表,其中包含要連接的表的所有列和行。
(2)WHERE
一旦我們擁有了總工作數據集,就會將第一遍WHERE
約束應用於各個行,並且丟棄不滿足約束的行。每個約束只能直接從FROM
子句中請求的表訪問列。SELECT
查詢部分中的別名在 大多數數據庫中都不可訪問,因爲它們可能包含依賴於尚未執行的查詢部分的表達式。
(3)GROUP BY
WHERE之
後,應用約束後的其餘行將根據GROUP BY
子句中指定的列中的公共值進行分組。作爲分組的結果,只有與該列中的唯一值一樣多的行。隱含地,這意味着只有在查詢中具有聚合函數時才需要使用它。
(4)HAVING
如果查詢具有GROUP BY
子句,則HAVING
子句中的約束將應用於分組行,丟棄不滿足約束的分組行。與該WHERE
子句一樣,在大多數數據庫中也無法從此步驟訪問別名。
(5)SELECT
SELECT
最後計算查詢部分中的任何表達式.
(6)DISTINGCT
在剩餘的行中,標記爲列的具有重複值的DISTINCT
行將被丟棄。
(7)
ORDER BY
如果ORDER BY
子句指定了一個訂單,那麼這些行將按指定的數據按升序或降序排序。由於SELECT
已經計算了查詢部分中的所有表達式,因此可以在此子句中引用別名。
(8)
LIMIT
/OFFSET
最後,落入由所指定的範圍之外的行LIMIT
和OFFSET
從查詢返回的被丟棄,在離開最後行的集合。
小結:並非每個查詢都需要包含上面列出的所有部分,但SQL的靈活性的一部分原因在於它允許開發人員和數據分析人員快速操作數據而無需編寫額外的代碼,所有這些都只是使用上述條款。
1.2 練習題
#1. 查找每個導演指導的電影數量
my:
SELECT title,director,count(*) FROM movies
group by director;
Sy:
SELECT director, COUNT(id) as Num_movies_directed
FROM movies
GROUP BY director;
#2. 查找可歸因於每位董事的國內和國際銷售總額
my 錯誤:
SELECT title,director, (domestic_sales + international_sales) AS TOTAL_SALES
FROM movies
RIGHT JOIN Boxoffice ON Movie.Id = Boxoffice.Movie_id
group by director;
最正確的:
SELECT director, SUM(domestic_sales + international_sales) as Cumulative_sales_from_all_movies
FROM movies
INNER JOIN boxoffice
ON movies.id = boxoffice.movie_id
GROUP BY director;
2. 第十三課 插入行
這節開始學習SQL模式以及如何添加親數據的知識。
2.1 知識點
模式:數據庫中的表被描述爲一組二維列表,列表是屬性,行表示實體中的實例,SQL中,數據庫中的模式描述了每個表的結構,以及表的每列可以包含的數據類型。
插入新數據
將數據插入數據庫時,需要使用一個INSERT語句,該語句聲明要寫入的表,正在填充的數據列以及要插入法的一行或多行數據。通常,插入的每行數據都應該包含表中每個相應列的值,可以按順序列出多個行,或一次插入多行。
插入包含所有列值的語句
INSERT INTO mytable
VALUES (value_or_expr, another_value_or_expr, …),
(value_or_expr_2, another_value_or_expr_2, …),
…;
在一些情況下,如果數據不完整且表中包含支持默認值的列,則可以通過顯示指定行來插入僅包含數據列的行。
插入包含特定列的語句
INSERT INTO mytable
(column, another_column, …)
VALUES (value_or_expr, another_value_or_expr, …),
(value_or_expr_2, another_value_or_expr_2, …),
…;
在這些情況下,值的數量需要與指定的列數相匹配。儘管這是一個更冗長的寫法陳述,但以這種方式插入值具有向前兼容的好處。例如,如果使用默認值向表中添加新列,則不會INSERT
更改硬編碼語句以適應該更改。
此外,可以將數學和字符串表達式與您要插入的值一起使用。
這有助於確保插入的所有數據都以某種方式格式化。
例使用表達式插入語句
INSERT INTO boxoffice
(movie_id, rating, sales_in_millions)
VALUES (1, 9.9, 283742034 / 1000000);
2.2 練習題
#1.將工作室的新作品“ 玩具總動員4”添加到電影列表中(您可以使用任何導演)
INSERT INTO MOVIE
VALUES(4,"Toy Story 4","PETER",2018,98)
#2.玩具總動員4已經獲得好評!它的評分爲8.7,國內爲3.4億,國際爲2.7億。將記錄添加到BoxOffice表中。
INSERT INTO boxoffice VALUES (4, 8.7, 340000000, 270000000);
3. 第十四課 更新行
3.1 知識點
更新現有數據,使用UPDATA語句來完成,與INSERT 語句相似,必須精確指定要更新的表,列和行,此外,更新的數據必須與模式中列的數據類型相匹配。
使用值更新語句
UPDATE mytable
SET column = value_or_expr,
other_column = another_value_or_expr,
…
WHERE condition;
該語句通過獲取多個列/值對,並將這些更改應用於滿足WHERE
子句中約束的每一行。
注意:首先編寫約束並在SELECT
查詢中對其進行測試,以確保更新正確的行,然後再寫入列/值對進行更新。
3.2 練習題
#1.A Bug's Life的導演不正確,實際上是由John Lasseter執導的
MY:運行不成功,但是覺得沒毛病
UPDATA movies
SET DIRECTOR = "John Lasseter"
WHERE TITLE= "A Bug's Life ";
正確的:
UPDATE movies
SET director = "John Lasseter"
WHERE id = 2;
#2. 玩具總動員2發佈的那一年是不正確的,它實際上是在1999年發佈的
UPDATE movies
SET year = 1999
WHERE id = 1;
#3.玩具總動員8的標題和導演都不正確!標題應爲“玩具總動員3”,由Lee Unkrich執導
UPDATE movies
SET title = "Toy Story 3",director="Lee Unkrich"
WHERE id = 11;
4. 第15課 刪除行
4.1 知識點
當需要從數據庫中的表中刪除數據時,可以使用一個DELETE
語句來描述要執行的表,以及要通過該WHERE
子句刪除的表的行。
刪除帶條件的語句
DELETE FROM mytable
WHERE condition;
如果決定省略WHERE
約束,則刪除所有行,這是一種快速簡便的方法來徹底清除表(如果是有意的)。
注意:與UPDATE
上一課中的語句一樣,建議SELECT
首先在查詢中運行約束, 以確保刪除正確的行。沒有適當的備份或測試數據庫,很容易不可撤銷地刪除數據,因此請始終閱讀您的DELETE
語句兩次並執行一次。
4.2 練習題
#1. 這個數據庫太大了,讓我們刪除2005年之前發佈的所有電影。
DELETE FROM movies
where year < 2005;
#2.Andrew Stanton也離開了工作室,所以請刪除他指導的所有電影。
DELETE FROM movies
where director="Andrew Stanton";