```sql
-- UPDATE Syntax
UPDATE *table_name*
SET *column1* = *value1*, *column2* = *value2*, ...
WHERE *condition*;
UPDATE student
SET age = 20
WHERE name = 'Alice';
-- DELETE Syntax
DELETE FROM table_name WHERE condition;
DELETE FROM Customers WHERE CustomerName='Alfreds Futterkiste';
-- 刪除 Table
DROP TABLE table_name;
DROP TABLE Shippers;
-- SELECT Syntax
SELECT column1, column2, ...
FROM table_name;
-- SELECT Syntax
SELECT * FROM mytable WHERE status IN ('Open', 'Pending');
-- SELECT DISTINCT Syntax
SELECT DISTINCT column1, column2, ...
FROM table_name;
-- INSERT INTO Syntax
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
-- INNER JOIN Syntax
SELECT column_name(s)
FROM table1
INNER JOIN table2
ON table1.column_name = table2.column_name;
-- CREATE INDEX Syntax
CREATE INDEX index_name
ON table_name (column1, column2, ...);
-- CREATE UNIQUE INDEX Syntax
CREATE UNIQUE INDEX index_name
ON table_name (column1, column2, ...);
-- ORDER BY Syntax
SELECT column1, column2, ...
FROM table_name
ORDER BY column1, column2, ... ASC|DESC;
-- ALTER TABLE - ADD Column
ALTER TABLE table_name
ADD column_name datatype;
-- example
ALTER TABLE Customers
ADD Email varchar(255) DEFAULT 'example@example.com' NOT NULL;
-- ALTER TABLE - DROP COLUMN
ALTER TABLE table_name
DROP COLUMN column_name;
-- example
ALTER TABLE Customers
DROP COLUMN Email;
-- ALTER TABLE - ALTER/MODIFY COLUMN
-- https://www.w3schools.com/sql/sql_alter.asp
-- SQL Server / MS Access
ALTER TABLE table_name
ALTER COLUMN column_name datatype;
-- My SQL / Oracle (prior version 10G):
ALTER TABLE table_name
MODIFY COLUMN column_name datatype;
-- Oracle 10G and later
ALTER TABLE table_name
MODIFY column_name datatype;
-- example
ALTER TABLE my_table
MODIFY record_date CHAR(2) DEFAULT TO_CHAR(SYSDATE, 'DD');
-- SQL COUNT()
SELECT COUNT(column_name)
FROM table_name
WHERE condition;
-- 多行註解
/*
SELECT COUNT(column_name)
FROM table_name
WHERE condition;
*/
```
```sql
-- SQL AUTO INCREMENT Field
CREATE TABLE Persons (
Personid int NOT NULL AUTO_INCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
City varchar(255) DEFAULT 'Sandnes',
Age int,
PRIMARY KEY (Personid)
);
```
```sql
-- SQL Data Types
https://www.w3schools.com/sql/sql_datatypes.asp
```
#### [The SQL INSERT INTO SELECT Statement](https://www.w3schools.com/sql/sql_insert_into_select.asp)
```sql
INSERT INTO table2 (column1, column2, column3, ...)
SELECT column1, column2, column3, ...
FROM table1
WHERE condition;
```
### 新增外鍵
在 SQL 中,您可以使用 `ALTER TABLE` 來更改資料表的結構。如果您想要在 `ALTER COLUMN` 時設定外鍵,您可以使用 `ADD CONSTRAINT` 來設定外鍵。以下是一個範例 SQL 語法:
```
ALTER TABLE table_name
ALTER COLUMN column_name datatype
ADD CONSTRAINT fk_constraint_name
FOREIGN KEY (column_name) REFERENCES foreign_table_name(foreign_column_name);
```
其中,`table_name` 是您想要更改的資料表名稱,`column_name` 是您想要更改的欄位名稱,`datatype` 是您想要設定的資料型態,`fk_constraint_name` 是您想要設定的外鍵名稱,`foreign_table_name` 是參考的資料表名稱,而 `foreign_column_name` 則是參考的欄位名稱。
### 修改外鍵
當您在資料表中使用外鍵時,您可以使用 `ALTER TABLE` 來更改資料表的結構。如果您想要修改已存在的外鍵,您可以使用 `ALTER TABLE` 來刪除現有的外鍵約束,然後再使用 `ADD CONSTRAINT` 來添加新的外鍵約束。以下是一個範例 SQL 語法:
```
ALTER TABLE table_name
DROP CONSTRAINT fk_constraint_name;
ALTER TABLE table_name
ADD CONSTRAINT fk_constraint_name
FOREIGN KEY (column_name) REFERENCES foreign_table_name(foreign_column_name);
```
在這個範例中,`table_name` 是包含您想要修改的外鍵約束的資料表名稱,而 `fk_constraint_name` 則是您想要修改的外鍵約束名稱。第一個 `ALTER TABLE` 語句刪除現有的外鍵約束,而第二個 `ALTER TABLE` 語句則添加了一個新的具有相同名稱的外鍵約束。
## MySQL
```sql
CREATE DATABASE test;
DROP DATABASE test;
USE test;
CREATE TABLE bands (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
PRIMARY KEY(id)
);
ALTER TABLE bands ADD another_column VARCHAR(255);
DROP TABLE tst_table;
CREATE TABLE albums (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
release_year INT,
band_id INT NOT NULL,
PRIMARY KEY(id),
FOREIGN KEY(band_id) REFERENCES bands(id)
);
INSERT INTO bands (name) VALUES ('Iron Maiden');
INSERT INTO bands (name) VALUES ('Duece'), ('Avenged Sevenfold'), ('Ankor');
SELECT * FROM bands;
SELECT * FROM bands LIMIT 2;
SELECT name FROM bands;
SELECT id AS 'ID', name AS 'Band Name' FROM bands;
SELECT * FROM bands ORDER BY name;
SELECT * FROM bands ORDER BY name ASC;
SELECT * FROM bands ORDER BY name DESC;
INSERT INTO albums (name, release_year, band_id)
VALUE ('The Number of Beasts', 1985, 1),
('Power Slave', 1984, 1),
('Nightmare', 2018, 2),
('Nightmare', 2010, 3),
('Test Album', NULL, 3);
SELECT DISTINCT name FROM albums;
UPDATE albums SET release_year = 1982 WHERE id = 1;
SELECT * FROM albums WHERE name LIKE '%er%';
SELECT * FROM albums WHERE name LIKE '%er%' OR band_id = 2;
SELECT * FROM albums WHERE release_year = 1984 AND band_id = 1;
SELECT * FROM albums WHERE release_year BETWEEN 2000 AND 2018;
SELECT * FROM albums WHERE release_year IS NULL;
DELETE FROM albums WHERE id = 5;
SELECT * FROM bands JOIN albums ON bands.id = albums.band_id;
SELECT * FROM bands INNER JOIN albums ON bands.id = albums.band_id;
SELECT * FROM bands LEFT JOIN albums ON bands.id = albums.band_id;
SELECT * FROM bands RIGHT JOIN albums ON bands.id = albums.band_id;
SELECT AVG(release_year) FROM albums;
SELECT SUM(release_year) FROM albums;
SELECT band_id, COUNT(band_id) FROM albums GROUP BY band_id;
SELECT b.name AS band_name, COUNT(a.id) AS num_albums
FROM band AS b
LEFT JOIN albums AS a ON b.id = a.band_id
GROUP BY b.id;
SELECT b.name AS band_name, COUNT(a.id) AS num_albums
FROM band AS b
LEFT JOIN albums AS a ON b.id = a.band_id
WHERE num_albums = 1
GROUP BY b.id;
SELECT b.name AS band_name, COUNT(a.id) AS num_albums
FROM band AS b
LEFT JOIN albums AS a ON b.id = a.band_id
WHERE b.name = 'Deuce'
GROUP BY b.id
HAVING num_albums = 1;
```
# 複製表格
要在 SQL 中複製一份表格 (Table),我們可以根據具體情況選擇不同的方法。以下我將提供兩種主要的方法:一個是復制表結構和數據,另一個只復制表結構。
### 方法一:複製表結構和數據
假設你想從一個已存在的表 `原始表格` 複製其結構及所有數據到一個新表 `新表格`,你可以使用下面的 SQL 指令:
```sql
CREATE TABLE 新表格 AS SELECT * FROM 原始表格;
```
這條指令的作用是創建一個名為 `新表格` 的新表,其內容和結構都是從 `原始表格` 中複制來的。
**範例:**
假設我們有一個叫作 `employees` 的表,我們想複制一份名為 `employees_backup`:
```sql
CREATE TABLE employees_backup AS SELECT * FROM employees;
```
### 方法二:僅複製表結構
如果你只想複製表格的結構而不包括其中的數據,你可以使用以下方法:
```sql
CREATE TABLE 新表格 AS SELECT * FROM 原始表格 WHERE 1=0;
```
這個指令會創建一個結構與 `原始表格` 相同的 `新表格`,但由於 `WHERE 1=0` 條件永遠不成立,因此不會複製任何數據。
**範例:**
假設我們有一個叫做 `employees` 的表,我們只想複製其結構到 `employees_structure`:
```sql
CREATE TABLE employees_structure AS SELECT * FROM employees WHERE 1=0;
```
這樣,`employees_structure` 會有相同的欄位設定,但不包含任何數據。
### 考慮事項
- 在複製大型表格時,需要考慮性能和儲存空間的問題。
- 被複製的表格中的索引、外鍵等約束條件可能不會被自動複制,你可能需要手動添加這些設定。
---
# GROUP BY
在 SQL 中,`GROUP BY`語句用於將來自一個或多個表的行分組在一起,以執行某些聚合函數,比如計算平均值(AVG)、最大值(MAX)、最小值(MIN)、總和(SUM)以及計數(COUNT)等。當你需要按照某一列或多列對數據進行分組統計時,就需要使用 `GROUP BY`。
### 使用時機:
1. **統計分類資料**:
當你需要對某個分類(例如各部門、各地區)的數據進行集計時。
2. **計算分組的聚合值**:
計算每個分組的總和、平均值、最大或最小值等。
3. **過濾聚合後的資料(通常與 `HAVING` 使用)**:
當需要基於聚合結果過濾數據時,如選擇銷售額超過一定數量的分組。
### 範例:
假設我們有一個名為 `Sales` 的表,表中含有 `Region`(地區)、`Salesperson`(銷售人員)和 `Amount`(銷售金額)等欄位。如果我們想要計算每個地區的總銷售金額,我們可以這樣寫:
```sql
SELECT Region, SUM(Amount) AS TotalSales
FROM Sales
GROUP BY Region;
```
這條 SQL 指令會按照 `Region` 分組,並計算每個地區的總銷售金額。
#### 更進一步的例子:
如果我們想進一步獲取銷售金額在一定數量以上的地區,我們可以結合 `HAVING` 使用:
```sql
SELECT Region, SUM(Amount) AS TotalSales
FROM Sales
GROUP BY Region
HAVING SUM(Amount) > 100000;
```
此語句將僅顯示那些銷售總金額超過 100,000 的地區及其銷售總金額。
通過這些例子,你可以看到 `GROUP BY` 的使用就是為了將數據按照一個或多個指定的列(分組的依據)進行分組,並對每個分組執行一個或多個聚合操作。這在數據分析和報表生成中非常有用。
# 重覆內容判斷
在 SQL 中,如果你想判斷一個欄位是否有重複的內容,你可以使用 `GROUP BY` 和 `HAVING` 這兩個語句來執行這項檢查。例如說,假設你有一個資料表名為 `Employees`,並且想要檢查員工的電子郵件地址 (email) 欄位中是否有重覆的值,以下是一個SQL查詢的示範:
```sql
SELECT email, COUNT(email) as NumOccurrences
FROM Employees
GROUP BY email
HAVING COUNT(email) > 1;
```
這條 SQL 查詢做了以下幾件事情:
1. 通過 `GROUP BY email` 聚集所有相同的電子郵件地址。
2. 使用 `COUNT(email)` 計算每個電子郵件地址出現的次數。
3. 使用 `HAVING COUNT(email) > 1` 過濾出那些出現次數超過一次的電子郵件地址,即重覆的電子郵件地址。
這樣,結果中會列出所有重複的電子郵件地址及其出現的次數。
假如你也想看到員工的名字,你可以稍微調整這個查詢,如下:
```sql
SELECT name, email, COUNT(email) as NumOccurrences
FROM Employees
GROUP BY email, name
HAVING COUNT(email) > 1;
```
這樣的查詢會顯示 email 重覆的員工的名字和 email,以及每組重覆的次數。注意,因為 `GROUP BY` 包括了 name,所以即使有相同的 email,只要名字不同也會被視為不同的項目。如果你只關心 email 的重覆而不在乎名字是否一樣,應該只用 `GROUP BY email`。