hello sql

前置條件

  1. 廖雪峯 sql 教程
  2. alasql github
  3. 新建一個項目 $ npm i alasql

一、基本語法

根據示例 https://github.com/agershun/alasql 學習基本語法

1.建表( CREATE TABLE)

alasql(`
CREATE TABLE users (age number, name string, money number);
`);

2. 插入數據(INSERT INTO {table})

alasql(`
INSERT INTO users VALUES (25,'張三', 100);
`):

然後確認一下數據是否真的寫入了

const mysql = alasql('

SELECT *FROM users;

');

console.log(mysql); // [ { age: 25, name: '張三', money: 100 } ]

於是寫個遍歷,插入更多數據,以供後面操作。

...
for(let i = 0; i< 100; i++) {
    const sql = `INSERT INTO users VALUES (${i}, '張${i}', ${i})`;
    alasql(sql);
}
const mysql = alasql('
SELECT * FROM users;
');
console.log(mysql);
// 輸出:
[ { age: 25, name: '張三', money: 100 },
  { age: 0, name: '張0', money: 0 },
  { age: 1, name: '張1', money: 1 },
  { age: 2, name: '張2', money: 2 },
  { age: 3, name: '張3', money: 3 },
  { age: 4, name: '張4', money: 4 },
// ...
 { age: 99, name: '張99', money: 99 },

3. SELECT 語句

望文生義, SELECT 就是選中,命中。選中的對象是啥呢?其實就是表的 “列” column。
舉例:

// 選中 users 表中所有的列
SELECT * FROM users;

// 只選中 name 這一列
SELECT name FROM users;

// 選中 name, age 兩列
 SELECT name,age FROM users;

如果希望返回的結果集可以自定義列名(column) ,這種操作稱之爲 “投影”, 可以使用語法 :

SELECT1 別名1,2 別名2 FROM users;

舉個 🌰:

// 原 column 名爲 name
...
[name]
張三
李四
王麻子
...

SELECT name '姓名' FROM users;
// 輸出
...
[姓名]
張三
李四
王麻子
...

4. WHERE 語句

現在,從表中篩選出 age > 90 的:

...
const mysql = alasql(`SELECT * FROM users WHERE age>90;`);
console.log(mysql);
// 輸出:
[ { age: 91, name: '張91', money: 91 },
  { age: 92, name: '張92', money: 92 },
  { age: 93, name: '張93', money: 93 },
  { age: 94, name: '張94', money: 94 },
  { age: 95, name: '張95', money: 95 },
  { age: 96, name: '張96', money: 96 },
  { age: 97, name: '張97', money: 97 },
  { age: 98, name: '張98', money: 98 },
  { age: 99, name: '張99', money: 99 } ]

5. 聯合條件

聯合條件,即多條件疊加。是爲了提高命中數據的準確度,達到準確查找想要數據的目的。

AND
...
const mysql = alasql(`SELECT * FROM users WHERE age=60 AND money=60;`);
console.log(mysql);
// 輸出:
[ { age: 60, name: '張60', money: 60 } ]
OR
...
const mysql = alasql(`SELECT * FROM users WHERE age=60 OR money=61;`);
console.log(mysql);
// 輸出:
 [ 
 { age: 60, name: '張60', money: 60 },
  { age: 61, name: '張61', money: 61 } 
  ]
NOT

查詢 !(age>=10)

...
const mysql = alasql(`SELECT * FROM users WHERE NOT age>=10;`);
console.log(mysql);
// 輸出:
[ { age: 0, name: '張0', money: 0 },
  { age: 1, name: '張1', money: 1 },
  { age: 2, name: '張2', money: 2 },
  { age: 3, name: '張3', money: 3 },
  { age: 4, name: '張4', money: 4 },
  { age: 5, name: '張5', money: 5 },
  { age: 6, name: '張6', money: 6 },
  { age: 7, name: '張7', money: 7 },
  { age: 8, name: '張8', money: 8 },
  { age: 9, name: '張9', money: 9 } ]

另一種,不等於的寫法:

// 又要大,又要小。又想馬兒跑,又不想給馬吃草
const mysql = alasql(`SELECT * FROM users WHERE  age<>20;`);
console.log(mysql);
// 輸出:
 ...
 [
  {age: 0, name: '張0'},
   ...
  { age: 18, name: '張18', money: 18 },
  { age: 19, name: '張19', money: 19 },
  // 注意,這裏 age=20 的數據被 where 語句命中了,因此沒有出現在結果集
  { age: 21, name: '張21', money: 21 },
  ... 
  { age: 99, name: '張99', money: 99 }
  ]

6.模糊查詢({field} LIKE)

// 查詢名字中以 `張7` 開頭的數據,% 代表任意字符。
const mysql = alasql(`SELECT * FROM users WHERE  name LIKE '張7%';`);
console.log(mysql);
// 輸出:
[ { age: 7, name: '張7', money: 7 },
  { age: 70, name: '張70', money: 70 },
  { age: 71, name: '張71', money: 71 },
  { age: 72, name: '張72', money: 72 },
  { age: 73, name: '張73', money: 73 },
  { age: 74, name: '張74', money: 74 },
  { age: 75, name: '張75', money: 75 },
  { age: 76, name: '張76', money: 76 },
  { age: 77, name: '張77', money: 77 },
  { age: 78, name: '張78', money: 78 },
  { age: 79, name: '張79', money: 79 } ]

7. 排序方式(ORDER BY {field} DESC/ASC)

細心的你肯定發現了,前面的數據都是按照順序(ASC 從小到大)來排序的,那如果我希望 age 或者 money 字段按照倒序(DESC 從大到小)來排布,該怎麼操作呢?

...
const mysql = alasql(`SELECT name '姓名' FROM users ORDER BY age DESC;`);
console.log(mysql);
// 輸出:
[ { '\'姓名\'': '張99' },
  { '\'姓名\'': '張98' },
  { '\'姓名\'': '張97' },
  { '\'姓名\'': '張96' },
  { '\'姓名\'': '張95' },
  ...
  ];

這裏我按照 age 的 DESC 來排序,結果符合預期。

8.分頁查詢( LIMIT, OFFSET)

之前做後臺管理的時候,我還納悶,爲什麼接口總是定義 offset=0;limit=10;orderBy=‘name’ 這樣的接口,現在看到這裏,應該都豁然開朗了。
在上述的例子裏,每次返回的結果集都太大,然而這個表只有 100 條數據而已,隨着表的規模越來越大,分頁查詢勢在必行。

...
// 返回的結果集極限大小爲 10 條數據,且從 index=0 的位置向後偏移 4 個
const mysql = alasql(`SELECT name FROM users LIMIT 10 OFFSET 4;`);
console.log(mysql);
// 輸出
[ { name: '張4' },
  { name: '張5' },
  { name: '張6' },
  { name: '張7' },
  { name: '張8' },
  { name: '張9' },
  { name: '張10' },
  { name: '張11' },
  { name: '張12' },
  { name: '張13' } ]

假表中設有無窮多的數據,需要查詢第 N 頁的數據,默認 LIMIT = 10,問 OFFSET = ?

OFFSET = LIMIT(N-1);

偏移量總是等於 = (要查詢的頁數 - 1)* limit

9.聚合查詢(SELECT COUNT(*) FROM {table})

const mysql = alasql(`SELECT COUNT(*) FROM users;`);
console.log(mysql);
// 輸出 ['COUNT(*)': 100]

同樣可以取別名

const mysql = alasql(`SELECT COUNT(*) total FROM users;`);
console.log(mysql);
// 輸出: [ { total: 100 } ]

另外,除了 COUNT 還有幾個內置函數:
MAX, MIN, AVG, SUM,FLOOR,CELING 等
對應最大,最小,平均,總和。

const mysql = alasql(`SELECT MAX(money) max FROM users;`);
console.log(mysql);
// 輸出  [ { max: 99 } ]
const mysql = alasql(`SELECT SUM(money) totalMoney FROM users;`);
console.log(mysql);
// [ { totalMoney: 4950 } ]

10.分組查詢(SELECT FROM {table} GROUP BY {field};)

const alasql = require('alasql');

alasql(`CREATE TABLE users (age number, name string, money number)`);

for (let i = 0; i < 10; i++) {
    // build random number as 1~10
    const number = Math.ceil(Math.random() * 10);
    const sql = `INSERT INTO users VALUES (${i}, '張${i}', ${number})`;
    alasql(sql);
}
const mysql = alasql(`SELECT * FROM users GROUP BY money ;`);
console.log(mysql);
// 輸出:
[ { money: 9 },
  { money: 8 },
  { money: 4 },
  { money: 3 },
  { money: 2 },
  { money: 7 },
  { money: 1 },
  { money: 10 } ]

11. 連接查詢(INNER JOIN … ON…)

顧名思義,即多個表連接到一起,統一查詢。
現在,假設每個 user 需要添加一個 company 字段,代表所處公司。而這個 company 是隨時會變動的,因此需要建立一個新表進行單獨的維護:

alasql(`
CREATE TABLE companies (id numnber, name string);
`);

companies 表很簡單,只有一個字段。
如果現在每個 user 的字段都要對應到 companies 的一個成員,即 users 長度 = companies 長度,該如何做映射呢?

const alasql = require('alasql');
// 創建兩個表,user 表中, company 爲數字,對應着 companies 表中的索引 id
alasql(`CREATE TABLE users (age number, name string, money number, company number)`);
alasql(`CREATE TABLE companies (id number, name string)`);
for (let i = 0; i < 10; i++) {
    // build random number as 1~10
    const number = Math.ceil(Math.random() * 10);
    const sql = `INSERT INTO users VALUES (${i}, '張${i}', ${number}, ${number})`;
    alasql(sql);
    // 這裏每個 company 的 id 應該與 user 表中的 company 字段 依次 相同
    alasql(`INSERT INTO companies VALUES (${number}, '公司' + ${number})`);
}

// 查詢時,多加一個 companies 表中的 name 列
const mysql = alasql(`
    SELECT u.age, u.name, u.money, c.name company_name
    FROM users u 
    INNER JOIN companies c 
    ON u.company=c.id
`);
console.log(mysql);
// 輸出:
[ { age: 0, name: '張0', money: 1, company_name: '公司1' },
  { age: 1, name: '張1', money: 2, company_name: '公司2' },
  { age: 1, name: '張1', money: 2, company_name: '公司2' },
  { age: 1, name: '張1', money: 2, company_name: '公司2' },
  { age: 1, name: '張1', money: 2, company_name: '公司2' },
  { age: 2, name: '張2', money: 7, company_name: '公司7' },
  { age: 2, name: '張2', money: 7, company_name: '公司7' },
  { age: 3, name: '張3', money: 4, company_name: '公司4' },
  { age: 3, name: '張3', money: 4, company_name: '公司4' },
  { age: 3, name: '張3', money: 4, company_name: '公司4' },
  { age: 4, name: '張4', money: 7, company_name: '公司7' },
  { age: 4, name: '張4', money: 7, company_name: '公司7' },
  { age: 5, name: '張5', money: 2, company_name: '公司2' },
  { age: 5, name: '張5', money: 2, company_name: '公司2' },
  { age: 5, name: '張5', money: 2, company_name: '公司2' },
  { age: 5, name: '張5', money: 2, company_name: '公司2' },
  { age: 6, name: '張6', money: 4, company_name: '公司4' },
  { age: 6, name: '張6', money: 4, company_name: '公司4' },
  { age: 6, name: '張6', money: 4, company_name: '公司4' },
  { age: 7, name: '張7', money: 4, company_name: '公司4' },
  { age: 7, name: '張7', money: 4, company_name: '公司4' },
  { age: 7, name: '張7', money: 4, company_name: '公司4' },
  { age: 8, name: '張8', money: 2, company_name: '公司2' },
  { age: 8, name: '張8', money: 2, company_name: '公司2' },
  { age: 8, name: '張8', money: 2, company_name: '公司2' },
  { age: 8, name: '張8', money: 2, company_name: '公司2' },
  { age: 9, name: '張9', money: 2, company_name: '公司2' },
  { age: 9, name: '張9', money: 2, company_name: '公司2' },
  { age: 9, name: '張9', money: 2, company_name: '公司2' },
  { age: 9, name: '張9', money: 2, company_name: '公司2' } ]

總結一下,這種多表聯合查詢,就是在 SELECT 階段選擇兩個表中的字段,然後通過 INNER JOIN {表名} ON {條件} 來完成的。
另外還有 LEFT OUTER JOIN , RIGHT OUTER JOIN 等,詳見廖雪峯大神總結的圖示:
在這裏插入圖片描述

二、CRUD BOY 的基本素養

1. 增

語法:

INSERT INTO table (field) VALUES (value1, value2...);
const alasql = require('alasql');
// 建表時可以註明類型
alasql(`CREATE TABLE users (age number, name string, money number)`);

for(let i = 0; i< 10; i++) {
    const sql = `INSERT INTO users VALUES (${i}, '張${i}', ${i})`;
    alasql(sql);
}

// 插入時不需要標註 field type
alasql(`INSERT INTO users (age, name, money) VALUES (1 , '大牛' , 100)`);
const mysql = alasql(`SELECT * FROM users;`);
console.log(mysql);
// 輸出:
[ { age: 0, name: '張0', money: 0 },
  { age: 1, name: '張1', money: 1 },
  { age: 2, name: '張2', money: 2 },
  { age: 3, name: '張3', money: 3 },
  { age: 4, name: '張4', money: 4 },
  { age: 5, name: '張5', money: 5 },
  { age: 6, name: '張6', money: 6 },
  { age: 7, name: '張7', money: 7 },
  { age: 8, name: '張8', money: 8 },
  { age: 9, name: '張9', money: 9 },
  { age: 1, name: '大牛', money: 100 } ]

2. 改

語法:

UPDATE <表名> SET 字段1=1, 字段2=2, ... WHERE ...;
...
// 更新 age=1 的這條數據
alasql(`UPDATE users  SET age=100000, money=200000 WHERE age=1`);
const mysql = alasql(`SELECT * FROM users;`);
console.log(mysql);
// 輸出:
[ { age: 0, name: '張0', money: 0 },
  { age: 100000, name: '張1', money: 200000 },
  { age: 2, name: '張2', money: 2 },
  { age: 3, name: '張3', money: 3 },
  { age: 4, name: '張4', money: 4 },
  { age: 5, name: '張5', money: 5 },
  { age: 6, name: '張6', money: 6 },
  { age: 7, name: '張7', money: 7 },
  { age: 8, name: '張8', money: 8 },
  { age: 9, name: '張9', money: 9 } ]

3. DELETE

語法:

DELETE FROM <表名> WHERE ...;
alasql(`DELETE FROM users WHERE age>5`);
const mysql = alasql(`SELECT * FROM users;`);
console.log(mysql);
// 輸出:
[ { age: 0, name: '張0', money: 0 },
  { age: 1, name: '張1', money: 1 },
  { age: 2, name: '張2', money: 2 },
  { age: 3, name: '張3', money: 3 },
  { age: 4, name: '張4', money: 4 },
  { age: 5, name: '張5', money: 5 } ]

4. Retrieve

語法:

SELECT colume FROM tableWHERE...
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章