掌握SQL,學習這30個實例就足夠了
SQL是一種編程語言,用于管理以表格形式(即表)存儲在關系數據庫中的數據。
關系數據庫由多個相互關聯的表組成。表之間的關系是在共享列的意義上形成的。
有許多不同的關系數據庫管理系統(例如MySQL,PostgreSQL,SQL Server)。他們采用的SQL語法可能略有不同。但是,兩者之間的差別很小,因此,如果您學習如何使用一種,則可以輕松切換到另一種。
在本文中,我們將介紹30個示例,這些示例涉及SQL的以下操作:
- 創建數據庫和表
- 將數據插入表
- 從表中刪除數據
- 更新表格
- 使用各種選擇語句查詢表
在您的計算機或云中有許多使用SQL的替代方法。我目前正在通過終端在Linux計算機上使用MySQL。另一個常用的替代方法是安裝MySQL Workbench。
實例1
我們首先從終端連接到MySQL服務器并創建一個數據庫。
- ~$ sudo mysql -u root
我們將被提示輸入密碼。現在,我們已連接到計算機中的MySQL服務器。
以下命令創建一個名為"零售"的數據庫。
- mysql> create database retail;
- mysql> use retail;
我們不在尚未包含任何表的零售數據庫中。
實例2
我們將首先使用create table命令創建一個名為" customer"的表。
- mysql> create table customer (
- -> cust_id int primary key,
- -> age int,
- -> location varchar(20),
- -> gender varchar(20)
- -> );
我們在括號內定義列的名稱和關聯的數據類型。將cust_id列指定為主鍵。
主鍵是唯一標識每一行的列。就像熊貓數據框的索引一樣。
實例3
我們將創建第二個表,稱為"訂單"。
- mysql> create table orders (
- -> order_id int primary key,
- -> date date,
- -> amount decimal(5,2),
- -> cust_id int,
- -> foreign key (cust_id) references customer(cust_id)
- -> on delete cascade
- -> );
在一開始,我們提到關系表通過共享列相互關聯。關聯兩個表的列是外鍵。
外鍵是將表與另一個表相關聯的東西。外鍵包含另一個表的主鍵。
訂單表中的cust_id列是外鍵,并將訂單表與客戶表相關。我們在創建表時指定此條件。
在最后一行,我們用"在刪除級聯上"短語指定另一個條件。它告訴MySQL當刪除客戶表中的一行時該怎么做。訂單表中的每一行都屬于一個客戶。客戶表中的每一行都包含一個唯一的客戶ID,并代表一個客戶。如果客戶表中的行被刪除,則意味著我們不再有該客戶。結果,屬于該客戶的訂單不再具有關聯的客戶ID。"刪除時級聯"表示沒有關聯客戶ID的訂單也將被刪除。
實例4
零售數據庫現在包含兩個表。我們可以使用show table命令查看數據庫中存在的表。
- mysql> show tables;
- +------------------+
- | Tables_in_retail |
- +------------------+
- | customer |
- | orders |
- +------------------+
注意:SQL中的命令以分號(";")結尾。
實例5
desc或describe命令從列名,數據類型和一些其他信息的角度概述了該表。
- mysql> desc orders;
- +----------+--------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +----------+--------------+------+-----+---------+-------+
- | order_id | int(11) | NO | PRI | NULL | |
- | date | date | YES | | NULL | |
- | amount | decimal(5,2) | YES | | NULL | |
- | cust_id | int(11) | YES | MUL | NULL | |
- +----------+--------------+------+-----+---------+-------+
實例6
我們可以修改現有表。例如,alter table命令可用于添加新列或刪除現有列。
讓我們在訂單表中添加一列" is_sale"。
- mysql> alter table orders add is_sale varchar(20);
我們編寫列名和數據類型以及add關鍵字。
- mysql> desc orders;
- +----------+--------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +----------+--------------+------+-----+---------+-------+
- | order_id | int(11) | NO | PRI | NULL | |
- | date | date | YES | | NULL | |
- | amount | decimal(5,2) | YES | | NULL | |
- | cust_id | int(11) | YES | MUL | NULL | |
- | is_sale | varchar(20) | YES | | NULL | |
- +----------+--------------+------+-----+---------+-------+
is_sale列已添加到訂單表中。
實例7
alter table也可以用于刪除語法稍有更改的列。
- mysql> alter table orders drop is_sale;
使用drop關鍵字而不是add關鍵字。我們也不必編寫數據類型來刪除列。
實例8
我們有表,但它們不包含任何數據。填充表的一種方法是insert語句。
- mysql> insert into customer values (
- -> 1000, 42, 'Austin', 'female'
- -> );
指定的值以相同的順序插入到列中。因此,我們需要保持順序一致。
實例9
我們可以通過分隔每一行來同時插入多行。
- mysql> insert into customer values
- -> (1001, 34, 'Austin', 'male'),
- -> (1002, 37, 'Houston', 'male'),
- -> (1003, 25, 'Austin', 'female'),
- -> (1004, 28, 'Houston', 'female'),
- -> (1005, 22, 'Dallas', 'male'),
- -> ;
我添加了一些行,并以相同的方式填充了orders表。
還有其他方法可以用數據填充表。例如,我們可以使用加載數據infile或加載數據本地infile語句來加載csv文件。
實例10
delete from語句可用于刪除表中的現有行。我們需要通過提供條件來標識要刪除的行。例如,下面的語句將刪除訂單ID為17的行。
- mysql> delete from orders
- -> where order_id = 17;
如果我們不指定條件,則刪除給定表中的所有行。
實例11
我們還可以更新現有行。讓我們更新訂單表中的一行。
- +----------+------------+--------+---------+
- | order_id | date | amount | cust_id |
- +----------+------------+--------+---------+
- | 1 | 2020-10-01 | 24.40 | 1001 |
- +----------+------------+--------+---------+
這是訂單表中的第一行。我們想將訂單金額更改為27.40。
- mysql> update orders
- -> set amount = 27.40
- -> where order_id = 1;
- mysql> select * from orders limit 1;
- +----------+------------+--------+---------+
- | order_id | date | amount | cust_id |
- +----------+------------+--------+---------+
- | 1 | 2020-10-01 | 27.40 | 1001 |
- +----------+------------+--------+---------+
我們將更新后的值寫在set關鍵字之后。通過在where關鍵字之后提供條件來標識要更新的行。
實例12
如果要通過復制現有表的結構來創建表,則可以使用帶有like關鍵字的create table語句。
- mysql> create table orders_copy like orders;
- mysql> show tables;
- +------------------+
- | Tables_in_retail |
- +------------------+
- | customer |
- | orders |
- | orders_copy |
- +------------------+
orders_copy表具有與orders表相同的結構,但不包含任何數據。
實例13
我們還可以通過使用create table和select語句一起使用數據創建現有表的副本。
- mysql> create table new_orders
- -> select * from orders;
似乎是兩個單獨的語句的組合。第一行創建表,第二行用orders表中的數據填充該表。
實例14
drop table語句可用于刪除數據庫中的表。
- mysql> drop table orders_copy, new_orders;
- mysql> show tables;
- +------------------+
- | Tables_in_retail |
- +------------------+
- | customer |
- | orders |
- +------------------+
我們已經成功刪除了在上一個示例中創建的表。
我們在數據庫中有兩個關系表。以下示例將說明我們如何使用選擇查詢從這些表中檢索數據。
實例15
最簡單的查詢是查看表中的所有列。
- mysql> select * from orders
- -> limit 3;
- +----------+------------+--------+---------+
- | order_id | date | amount | cust_id |
- +----------+------------+--------+---------+
- | 1 | 2020-10-01 | 27.40 | 1001 |
- | 2 | 2020-10-01 | 36.20 | 1000 |
- | 3 | 2020-10-01 | 65.45 | 1002 |
- +----------+------------+--------+---------+
" *"選擇所有列,而limit關鍵字對要顯示的行數施加約束。
實例16
通過寫列名而不是" *",我們只能選擇某些列。
- mysql> select order_id, amount
- -> from orders
- -> limit 3;
- +----------+--------+
- | order_id | amount |
- +----------+--------+
- | 1 | 27.40 |
- | 2 | 36.20 |
- | 3 | 65.45 |
- +----------+--------+
實例17
我們可以使用where子句指定要選擇的行的條件。以下查詢將返回2020–10–01的所有訂單。
- mysql> select * from orders
- -> where date = '2020-10-01';
- +----------+------------+--------+---------+
- | order_id | date | amount | cust_id |
- +----------+------------+--------+---------+
- | 1 | 2020-10-01 | 27.40 | 1001 |
- | 2 | 2020-10-01 | 36.20 | 1000 |
- | 3 | 2020-10-01 | 65.45 | 1002 |
- +----------+------------+--------+---------+
實例18
where子句接受多個條件。讓我們在上一個示例中為查詢添加另一個條件。
- mysql> select * from orders
- -> where date = '2020-10-01' and amount > 50;
- +----------+------------+--------+---------+
- | order_id | date | amount | cust_id |
- +----------+------------+--------+---------+
- | 3 | 2020-10-01 | 65.45 | 1002 |
- +----------+------------+--------+---------+
實例19
我們可能想對查詢結果進行排序,這可以通過使用order by子句來完成。
以下查詢將返回2020–10–02的訂單,并根據金額對它們進行排序。
- mysql> select * from orders
- -> where date = '2020-10-02'
- -> order by amount;
- +----------+------------+--------+---------+
- | order_id | date | amount | cust_id |
- +----------+------------+--------+---------+
- | 5 | 2020-10-02 | 18.80 | 1005 |
- | 6 | 2020-10-02 | 21.15 | 1009 |
- | 4 | 2020-10-02 | 34.40 | 1001 |
- | 7 | 2020-10-02 | 34.40 | 1008 |
- | 8 | 2020-10-02 | 41.10 | 1002 |
- +----------+------------+--------+---------+
實例20
默認情況下,order by子句對行進行升序排序。我們可以使用desc關鍵字將其更改為降序。
- mysql> select * from orders
- -> where date = '2020-10-02'
- -> order by amount desc;
- +----------+------------+--------+---------+
- | order_id | date | amount | cust_id |
- +----------+------------+--------+---------+
- | 8 | 2020-10-02 | 41.10 | 1002 |
- | 4 | 2020-10-02 | 34.40 | 1001 |
- | 7 | 2020-10-02 | 34.40 | 1008 |
- | 6 | 2020-10-02 | 21.15 | 1009 |
- | 5 | 2020-10-02 | 18.80 | 1005 |
- +----------+------------+--------+---------+
實例21
SQL是一種通用語言,也可以用作數據分析工具。它提供許多功能,可在從數據庫查詢時分析和轉換數據。
例如,我們可以在訂單表中計算唯一天數。
- mysql> select count(distinct(date)) as day_count
- -> from orders;
- +-----------+
- | day_count |
- +-----------+
- | 4 |
- +-----------+
訂單表包含4個不同日期的訂單。" as"關鍵字用于重命名查詢結果中的列。否則,該列的名稱將為" count(distinct(date))"。
實例22
訂單表中有4天。我們還可以找出每天有多少訂單。group by子句將幫助我們完成此任務。
- mysql> select date, count(order_id) as order_count
- -> from orders
- -> group by date;
- +------------+-------------+
- | date | order_count |
- +------------+-------------+
- | 2020-10-01 | 3 |
- | 2020-10-02 | 5 |
- | 2020-10-03 | 6 |
- | 2020-10-04 | 2 |
- +------------+-------------+
我們計算訂單并將其按日期列分組。
實例23
我們將計算每天的平均訂單金額,并根據平均金額以降序排列結果。
- mysql> select date, avg(amount)
- -> from orders
- -> group by date
- -> order by avg(amount) desc;
- +------------+-------------+
- | date | avg(amount) |
- +------------+-------------+
- | 2020-10-01 | 43.016667 |
- | 2020-10-04 | 42.150000 |
- | 2020-10-03 | 37.025000 |
- | 2020-10-02 | 29.970000 |
- +------------+-------------+
實例24
我們要修改上一個示例中的查詢,并且只包含平均金額大于30的天。
- mysql> select date, avg(amount)
- -> from orders
- -> group by date
- -> having avg(amount) > 30
- -> order by avg(amount) desc;
- +------------+-------------+
- | date | avg(amount) |
- +------------+-------------+
- | 2020-10-01 | 43.016667 |
- | 2020-10-04 | 42.150000 |
- | 2020-10-03 | 37.025000 |
重要的是要注意,查詢中語句的順序很重要。例如,如果將order by子句放在having子句之前,則會產生錯誤。
實例25
我們想找出每天的最大訂購量。
- mysql> select date, max(amount)
- -> from orders
- -> group by date;
- +------------+-------------+
- | date | max(amount) |
- +------------+-------------+
- | 2020-10-01 | 65.45 |
- | 2020-10-02 | 41.10 |
- | 2020-10-03 | 80.20 |
- | 2020-10-04 | 50.10 |
實例26
我們要在select語句中組合多個聚合函數。為了說明這一點,讓我們詳細說明前面的示例。我們希望看到每個客戶的最大訂單量與最小訂單量之間的差異。我們還希望根據升序的差異對結果進行排序,并顯示前三個結果。
- mysql> select cust_id, max(amount) - min(amount) as dif
- -> from orders
- -> group by cust_id
- -> order by dif desc
- -> limit 3;
- +---------+-------+
- | cust_id | dif |
- +---------+-------+
- | 1007 | 46.00 |
- | 1009 | 28.95 |
- | 1002 | 24.35 |
- +---------+-------+
diff列是通過從最大數量減去最小數量獲得的。
實例27
我們現在切換到客戶表。讓我們找出每個城市有多少女性和男性顧客。我們需要在group by子句中同時寫位置和性別列。
- mysql> select location, gender, count(cust_id)
- -> from customer
- -> group by location, gender;
- +----------+--------+----------------+
- | location | gender | count(cust_id) |
- +----------+--------+----------------+
- | Austin | female | 2 |
- | Austin | male | 1 |
- | Dallas | female | 2 |
- | Dallas | male | 2 |
- | Houston | female | 2 |
- | Houston | male | 1 |
- +----------+--------+----------------+
實例28
客戶表和訂單表基于cust_id列相互關聯。我們可以使用SQL連接從兩個表中查詢數據。
我們希望在客戶表中查看每個城市的平均訂單金額。
- mysql> select customer.location, avg(orders.amount) as avg
- -> from customer
- -> join orders
- -> on customer.cust_id = orders.cust_id
- -> group by customer.location;
- +----------+-----------+
- | location | avg |
- +----------+-----------+
- | Austin | 33.333333 |
- | Dallas | 34.591667 |
- | Houston | 44.450000 |
- +----------+-----------+
由于我們從兩個不同的表中選擇列,因此將使用關聯的表名指定列名。上面查詢的第二,第三和第四行基于每個表中的cust_id列將customer andorders表聯接在一起。
請注意,列名不必相同。無論我們使用" on"關鍵字提供什么列名,都將基于這些列進行比較或匹配。
實例29
我們希望查看在2020–10–03年下訂單的客戶的平均年齡。
- mysql> select avg(c.age) as avg_age
- -> from customer c
- -> join orders o
- -> on c.cust_id = o.cust_id
- -> where o.date = '2020-10-03';
- +---------+
- | avg_age |
- +---------+
- | 30.0000 |
- +---------+
我們也可以為表名使用別名。當我們需要多次鍵入表名時,它很方便。
實例30
我們想查看訂單量最大的客戶的位置。
- mysql> select c.location, o.amount
- -> from customer c
- -> join orders o
- -> on c.cust_id = o.cust_id
- -> where o.amount = (select max(amount) from orders)
- -> ;
- +----------+--------+
- | location | amount |
- +----------+--------+
- | Dallas | 80.20 |
- +----------+--------+
在此查詢中,我們有一個嵌套的select語句。金額條件是使用訂單表中單獨的select語句計算得出的。
可以通過其他方式完成此任務。我選擇了這種方法來介紹嵌套查詢的概念。
結論
我相信本文中的30個示例將全面介紹SQL。我們涵蓋了以下主題:
- 用關系表創建數據庫
- 修改表格
- 將數據插入表
- 從表中刪除數據
- 編寫查詢以從表中檢索數據
當然,SQL可以完成更高級的查詢和操作。熟悉基礎知識后,最好繼續進行更高級的操作。
原文鏈接:https://towardsdatascience.com/30-examples-to-master-sql-c8004705479a