用JOINs進行多表聯合查詢
但是在現實數據庫中往往包含一組相關的數據表,這些表一般會符合數據庫范式(normalization)[1]. 讓我們先了解下關系數據庫的范式
數據庫范式(normalization)
數據庫范式是數據表設計的規范,在范式規范下,數據庫里每個表存儲的重復數據降到最少(這有助於數據的一致性維護),同時在數據庫范式下,表和表之間不再有很強的數據耦合,可以獨立的增長 (ie. 比如汽車引擎的增長和汽車的增長是完全獨立的). 范式帶來了很多好處,但隨着數據表的分離,意味着我們要查詢多個數據屬性時,需要更復雜的SQL語句,也就是本節開始介紹的多表連接技術。這樣SQL的性能也會面臨更多的挑戰,特別是當大數據量的表很多的情況下.
如果一個實體(比如Dog)的屬性數據被分散到多個數據表中,我們就需要學習如何通過 JOIN
連表技術來整合這些數據並找到我們想要查詢的數據項.
主鍵:
主鍵(primary key)
, 一般關系數據表中,都會有一個屬性列設置為 主鍵(primary key)
。主鍵是唯一標識一條數據的,不會重復復(想象你的身份證號碼)。一個最常見的主鍵就是auto-incrementing integer(自增ID,每寫入一行數據ID+1, 當然字符串,hash值等只要是每條數據是唯一的也可以設為主鍵.
借助主鍵(primary key)
(當然其他唯一性的屬性也可以),我們可以把兩個表中具有相同 主鍵ID的數據連接起來(因為一個ID可以簡要的識別一條數據,所以連接之后還是表達的同一條數據)(你可以想象一個左右連線游戲)。具體我們用到 JOIN
關鍵字。我們先來學習 INNER JOIN
.
多表聯合句式:
SELECT column, another_table_column, … FROM mytable (主表)
INNER JOIN another_table (要連接的表)
ON mytable.id = another_table.id (想象一下剛才講的主鍵連接,兩個相同的連成1條)
WHERE condition(s) ORDER BY column, … ASC/DESC LIMIT num_limit OFFSET num_offset;
實戰:
有兩個電影表,電影信息表格Movies , BoxOffice 存儲着市場相關的信息
Table: Movies
Id | Title | Director | Year | Length_minutes |
1 | Toy Story | John Lasseter | 1995 | 81 |
2 | A Bug's Life | John Lasseter | 1998 | 95 |
3 | Toy Story 2 | John Lasseter | 1999 | 93 |
4 | Monsters, Inc. | Pete Docter | 2001 | 92 |
5 | Finding Nemo | Finding Nemo | 2003 | 107 |
6 | The Incredibles | Brad Bird | 2004 | 116 |
7 | Cars | John Lasseter | 2006 | 117 |
8 | Ratatouille | Brad Bird | 2007 | 115 |
9 | WALL-E | Andrew Stanton | 2008 | 104 |
10 | Up | Pete Docter | 2009 | 101 |
11 | Toy Story 3 | Lee Unkrich | 2010 | 103 |
12 | Cars 2 | John Lasseter | 2011 | 120 |
13 | Brave | Brenda Chapman | 2012 | 102 |
14 | Monsters University | Dan Scanlon | 2013 | 110 |
Table: Boxoffice
Movie_id | Rating | Domestic_sales | International_sales |
5 | 8.2 | 380843261 | 555900000 |
14 | 7.4 | 268492764 | 475066843 |
8 | 8 | 206445654 | 417277164 |
12 | 6.4 | 191452396 | 368400000 |
3 | 7.9 | 245852179 | 239163000 |
6 | 8 | 261441092 | 370001000 |
9 | 8.5 | 223808164 | 297503696 |
11 | 8.4 | 415004880 | 648167031 |
1 | 8.3 | 191796233 | 170162503 |
7 | 7.2 | 244082982 | 217900167 |
10 | 8.3 | 293004164 | 438338580 |
4 | 8.1 | 289916256 | 272900000 |
2 | 7.2 | 162798565 | 200600000 |
13 | 7.2 | 237283207 | 301700000 |
任務:
1.找到所有電影的線下Domestic_sales
和線上銷售額
SELECT * FROM Movies inner join Boxoffice on Movies.id=Boxoffice.Movie_id
2.找到所有線上銷售額比線下銷售大的電影
SELECT * FROM Movies inner join Boxoffice on Movies.id=Boxoffice.Movie_id where Boxoffice.International_sales>Boxoffice.Domestic_sales
3.找出所有電影按市場占有率rating
倒序排列
SELECT * FROM Movies inner join Boxoffice on Movies.id=Boxoffice.Movie_id order by Boxoffice.rating desc
4.每部電影按線上銷售額比較,排名最靠前的導演是誰,線上銷量多少
SELECT movies.Director,Boxoffice.International_sales FROM Movies inner join Boxoffice on Movies.id=Boxoffice.Movie_id order by Boxoffice.International_sales desc limit 1