---
# System prepended metadata

title: SQL語法筆記

---

# SQL語法筆記
萬物皆從SELECT開始

假設有個hero資料表

```ruby
rails new g model Hero name gender age:integer hero_level hero_rank:integer description:text
#hero_level 有Ｓ、Ａ、Ｂ、Ｃ四個等級
#hero_rank 與id的流水編號不同，代表著英雄的實力排名
```

在SQL大小寫沒有影響，但是大寫代表著重要語法
註解所寫的是在rails的model使用的寫法

## SELECT
### 選取資料

```sql=
SELECT *
FROM heroes
-- Hero.all
```

上面所寫的是選取Hero表單的全部



---


當我要找s級，也就是hero_level = "s" 的英雄

```sql=
SELECT *
FROM heroes
WHERE hero_level = "s";
-- Hero.where(hero_level: "s")
```
使用WHERE去進一步的塞選

---
當我要找s級的女性英雄
```sql=
SELECT *
FROM heroes
WHERE hero_level = "s" AND gender = "F";
-- Hero.where(hero_level: "s" , gender: "F")
```
使用AND去增加塞選的條件，如果還想再加條件，再一個AND



---

找age沒有寫，年齡不明的英雄
```sql=
SELECT name,age
FROM heroes
WHERE age is NULL;
-- Hero.select(name,age).where(age: nil)
```
在找null的時候會使用 **is** 而不是 **=**
select 寫上條件就可以只列出條件的部分而不是全部

---

找到名字有“背心”這兩個字的英雄的id
```sql=
SELECT id
FROM heroes
WHERE name like "%背心%";
-- Hero.where("name like ?" ,"%背心%")
```
搜尋特定字的時候，使用**like**，**％**代表著背心前面或後面的字。
因為在rails沒有尋找的方法，所以會用"xxx like ?"


---
找10~25歲的英雄
有兩種寫法
```sql=
SELECT *
FROM heroes
WHERE age >=10 AND age <= 25;
-- Hero.where(age: 10..25)
```
```sql=
SELECT *
FROM heroes
WHERE age BETWEEN 10 AND 25;
-- Hero.where(age: 10..25)
```
可以使用**AND**單純的設下兩個條件。
或者也可以用**BETWEEN** 10 **AND** 25 


---
找出Ｓ級與Ａ級的英雄
```sql=
SELECT *
FROM heroes
WHERE hero_level ="s" OR hero_level ="A";
-- Hero.where(hero_level: ["S","A"])
```
```sql=
SELECT *
FROM heroes
WHERE hero_level IN ("S","A");
-- Hero.where(hero_level: ["S","A"])
```
在選取複數條件時，可用**IN**


---
找不是Ｓ級的英雄
```sql=
SELECT *
FROM heroes
WHERE hero_level != "S";
-- Hero.where.not(hero_level: "S")
```
```sql=
SELECT *
FROM heroes
WHERE hero_level <> "S";
-- Hero.where.not(hero_level: "S")
```
```sql=
SELECT *
FROM heroes
WHERE not hero_level = "S";
-- Hero.where.not(hero_level: "S")
```

## UPDATE
### 更新資料

```sql=
UPDATE heroes
SET age = 10
WHERE id = 25;
-- Hero.find(25).update(age: 10)
```
把 id為25的英雄，age 改為 10
在這邊要注意，**WHERE一定要寫！！！**
不然所有的英雄age都會變成10


---
## DELETE
### 刪除資料
刪除所有Ａ級英雄

```sql=
DELETE heroes
WHERE  hero_level = "A";
-- Hero.where(hero_level: "A").destroy
```
**一樣要注意ＷＨＥＲＥ！！！**
沒有寫資料就會全部刪除
可以準備跑路了


---
### 計算總數

不是Ｓ級的英雄有幾位
```sql=
SELECT count(*)
FROM heroes
WHERE not hero_level = "S";
-- Hero.where.not(hero_level: "S").count
```
在SELECT加上count可以計算其數量


---
### 加總＆平均＆最大＆最小

A級英雄的age年齡合
```sql=
SELECT sum(age)
FROM heroes
WHERE  hero_level = "A";
-- Hero.where.(hero_level: "Ａ").sum(:age)
```
平均就換成avg
```sql=
SELECT avg(age)
FROM heroes
WHERE  hero_level = "A";
-- Hero.where.(hero_level: "Ａ").average
```
同上，找age最大就改成**max**找最小就改成**min**

---
### 分組
```sql=
SELECT hero_level,avg(age)
FROM heroes
WHERE  hero_level;
```
分別印出Ｓ、Ａ、Ｂ、Ｃ級的age的平均值


---
### 去除重複
```sql=
SELECT DISTINCT hero_level
FROM heroes
```
印出S、A、Ｂ、Ｃ


---
### 排序
英雄實力的排行
```sql=
SELECT *
FROM heroes
ORDER BY hero_rank;
-- Hero.where(hero_level: "s" , gender: "F")
```
反過來的話就在hero_rank後面加上 DESC


---
### 限量
英雄實力的排行前十名
```sql=
SELECT *
FROM heroes
ORDER BY hero_rank LIMIT 10;
-- Hero.where(hero_level: "s" , gender: "F").limit(10)
```
使用LIMIT限制其數量


---
