---
# System prepended metadata

title: SQL常用語法

---

# SQL常用語法


### select 語法
```sql
SELECT * FROM tableName;    --查詢所有欄位
SELECT column1, column2 FROM tableName; --指定欄位查詢

--條件查詢
--比較運算子: = > >= < <= <> !=

SELECT * FROM tableName WHERE 條件; 
SELECT * FROM tableName WHERE column1 >= 10 AND column2 = 'some_value';
SELECT * FROM tableName WHERE column1 = 10 OR column2 = 20;

--是否存在於預設清單內 IN and NOT IN
SELECT * FROM tableName WHERE column IN ('10', '20', '30');
SELECT * FROM tableName WHERE column NOT IN ('10', '20', '30');

--範圍查詢：使用 BETWEEN/NOT BETWEEN 子句查詢某個範圍內的資料
SELECT * FROM tableName WHERE column1 BETWEEN 10 AND 20;
SELECT * FROM tableName WHERE column1 NOT BETWEEN 10 AND 20;

--使用 DISTINCT 語法查詢不重複的資料
SELECT DISTINCT column1, column2, ... FROM table_name; 

SELECT column FROM tableName WHERE column LIKE %條件%; --模糊條件查詢

--排序查詢。若無輸入，預設 ASC
SELECT column1 FROM tableName ORDER BY column2 ASC/DESC;

--使用 OFFSET 子句設置查詢結果的偏移量，以實現分頁功能
--從第十筆開始撈五筆
SELECT * FROM tableName LIMIT 5 OFFSET 10;
SELECT * FROM tableName LIMIT 5; --限制查詢數量, 五筆

--NULL 值判斷：使用 IS NULL 或 IS NOT NULL 判斷欄位中是否為 NULL 值
SELECT * FROM tableName WHERE column1 IS NULL;
SELECT * FROM tableName WHERE column1 IS NOT NULL;

--分組聚合：使用 GROUP BY 子句將資料分組後進行聚合計算
--AVG, 平均
SELECT account, AVG(score) 
FROM user_score
WHERE 條件 --非必要
GROUP BY account;

SELECT account, AVG(score) 
FROM user_score 
WHERE subject = 'Math' 
GROUP BY account;

--取小數第二位，第一種寫法
SELECT account, ROUND(AVG(score)::numeric, 2) 
FROM user_score
GROUP BY account;

--取小數第二位，第二種寫法
SELECT account, ROUND(AVG(CAST(score AS numeric)), 2) 
FROM user_score 
GROUP BY account;

--SUM, 加總
SELECT account, SUM(score) 
FROM user_score 
WHERE 條件 --非必要
GROUP BY account;

SELECT account, SUM(score) 
FROM user_score 
WHERE subject = 'Math' 
GROUP BY account;

--MIN MAX 最小值，最大值
SELECT account, MAX(score), MIN(score) 
FROM user_score 
WHERE subject = 'Math' 
GROUP BY account;

--COUNT 查詢筆數
SELECT COUNT(*) FROM table1;    --計算總筆數
SELECT COUNT(column) FROM tableName;    --針對特定欄位計算
SELECT COUNT(DISTINCT column) FROM tableName;    --去除重複資料

--聯合查詢
SELECT columnName FROM tableName1 UNION SELECT columnName FROM tableName2;
--聯合查詢（去除重複資料）
SELECT columnName FROM tableName1 UNION DISTINCT SELECT columnName FROM tableName2。
--從多個表格中選擇資料：可以使用 JOIN 子句將多個表格中的資料連接起來
SELECT * FROM table1 JOIN table2 ON table1.column1 = table2.column2;
--各種 join 範例
select a.account, a.name, b.subject, b.score from my_user2 a, user_score b where a.account = b.account;
select a.account, a.name, b.subject, b.score from my_user2 a inner join user_score b on a.account = b.account;
select a.account, a.name, b.subject, b.score from my_user2 a left outer join user_score b on a.account = b.account;
select a.account, a.name, b.subject, b.score from my_user2 a left join user_score b on a.account = b.account order by account asc;
select a.account, a.name, b.subject, b.score from my_user2 a right join user_score b on a.account = b.account order by account asc;

--子查詢：使用子查詢將一個查詢結果作為另一個查詢的輸入
SELECT * FROM table1 WHERE column1 = (SELECT column2 FROM table2);

--資料轉換：使用 CAST 或 CONVERT 函數將欄位中的資料轉換為不同的資料類型
SELECT CAST(column1 AS INTEGER) FROM table1;

--使用 HAVING 語法對分組結果進行篩選：
SELECT column1, column2, ... FROM table_name GROUP BY column1, column2, ... HAVING condition;
```

### insert 語法
```sql
--一般的 INSERT：
INSERT INTO mytable VALUES ('value1', 'value2', 'value3');	//不建議
INSERT INTO mytable (col1, col2, col3) VALUES ('value1', 'value2', 'value3');

--INSERT 選取另一個表格的資料：
INSERT INTO mytable (col1, col2, col3)
SELECT othercol1, othercol2, othercol3 FROM othertable WHERE condition;

--INSERT 多筆資料：
INSERT INTO mytable (col1, col2, col3) VALUES 
('value1', 'value2', 'value3'), 
('value4', 'value5', 'value6');

--INSERT 不存在的資料，如果已經存在就忽略：
INSERT INTO mytable (col1, col2, col3)
VALUES ('value1', 'value2', 'value3')
ON CONFLICT DO NOTHING;

--INSERT 已經存在的資料，如果已經存在就更新：
INSERT INTO mytable (col1, col2, col3)
VALUES ('value1', 'value2', 'value3')
ON CONFLICT (col1) 
DO UPDATE SET col2 = EXCLUDED.col2, col3 = EXCLUDED.col3;

--插入預設值
INSERT INTO mytable (id, name, age, address) 
    VALUES (1, 'John', DEFAULT, DEFAULT);

--插入預設值EXAMPLE
INSERT INTO my_user2 (account, password, name, test) 
    VALUES ('account123', 'passwd123', 'Johnny', DEFAULT);
INSERT INTO my_user2 (account, password, name) 
    VALUES ('account456', 'passwd456', 'Walker');
```

### update 語法
```sql
--更新單一欄位：
--這會將 my_table 表格中 id 為 1 的列的 column1 欄位更新為 'new_value'。
UPDATE my_table SET column1 = 'new_value' WHERE id = 1;

--更新多個欄位：
--這會將 my_table 表格中 id 為 1 的列的 column1 欄位更新為 'new_value1'，
--將 column2 欄位更新為 'new_value2'。
UPDATE my_table SET column1 = 'new_value1', column2 = 'new_value2' WHERE id = 1;

--更新符合條件的多個列：
--這會將 my_table 表格中所有 column2 欄位值為 'some_value' 的列
--的 column1 欄位更新為 'new_value'。
UPDATE my_table SET column1 = 'new_value' 
WHERE column2 = 'some_value';

--使用子查詢更新：
--這會將 my_table 表格中所有 id 值在子查詢中選出，
--且 other_table 表格中 column2 欄位值為 'some_value' 的列
--的 column1 欄位更新為 'new_value'。
UPDATE my_table SET column1 = 'new_value' 
WHERE id IN (SELECT id FROM other_table WHERE column2 = 'some_value');

UPDATE mytable SET column1 = 
(SELECT column2 FROM anothertable WHERE id = 1) WHERE id = 2;

--根據 JOIN 來更新欄位：
UPDATE mytable SET column1 = 'new_value'
FROM myothertable WHERE mytable.id = myothertable.id
AND myothertable.condition = true;
```

### delete 語法
```sql
--刪除特定行
DELETE FROM my_table
WHERE column1 = 'value1';

--刪除所有行
DELETE FROM my_table;

--刪除來自另一個表格的匹配行
DELETE FROM my_table
WHERE column1 IN (
  SELECT column1 FROM another_table WHERE column2 = 'value2'
);

--使用 JOIN 刪除來自多個表格的匹配行
DELETE my_table
FROM my_table
JOIN another_table ON my_table.column1 = another_table.column1
WHERE another_table.column2 = 'value2';
```
### DDL語法
```sql
--CREATE DATABASE
--創建一個名為mydb的新資料庫：
CREATE DATABASE mydb;

--ALTER DATABASE
--將mydb資料庫的擁有者更改為新擁有者new_owner：
ALTER DATABASE mydb OWNER TO new_owner;

--DROP DATABASE
--刪除mydb資料庫：
DROP DATABASE mydb;

--CREATE TABLE
--創建一個名為users的新表，該表包含id（主鍵）、name和age三個欄位：
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    age INTEGER
);

--ALTER TABLE
--將users表的age欄位修改為new_age，並更改其數據類型為BIGINT：
ALTER TABLE users
ALTER COLUMN age TYPE BIGINT
RENAME TO new_age;

--DROP TABLE
--刪除名為users的表：
DROP TABLE users;

--CREATE INDEX
--創建一個名為idx_name的索引，該索引適用於users表中的name欄位：
CREATE INDEX idx_name
ON users (name);

--DROP INDEX
--刪除名為idx_name的索引：
DROP INDEX idx_name;
```

### 其他補充
```sql
--字串連接
SELECT *, first_name || ' ' || last_name AS full_name
FROM customer;

--使用內建函數
    SELECT char_length(first_name), first_name    --字串長度
    FROM customer;

    SELECT upper(first_name), first_name    --轉大寫
    FROM customer;

    SELECT lower(first_name), first_name    --轉小寫
    FROM customer;

    --分割字串 (結果 hom, hom)
    SELECT substring('Thomas' from 2 for 3), substr('Thomas',2, 3);

    --查找字元 (結果 ab, de)
    SELECT left('abcde', 2), right('abcde', 2);

    --無條件捨去, 無條件進位, 四捨五入, 取小數第二位
    SELECT ceil(-42.8), floor(-42.8), round(12.45), round(12.54), trunc(12.8124, 2);

    --平方, 開根號, 立方根
    SELECT power(2, 3), sqrt(4), cbrt(27);

--清空指定的資料表
truncate tableName

--直接計算
select 2 + 3 as total;
select 3 % 2 as "mod";

--條件表示式
SELECT account, subject, score,
   CASE
       WHEN score >= 90 THEN 'A'
       WHEN score >= 80 THEN 'B'
       WHEN score >= 70 THEN 'C'
       WHEN score >= 60 THEN 'D'
       ELSE 'E'
   END AS grade
FROM user_score;
```
