# Oracle?SAP?鼎新?淺談這些ERP背後的是什麼-SQL資料庫
# 前言
記得在某次外勤的時候,那時候好像是要做稅抽還是要查什麼東西,需要用客戶的電腦SAP裡面查一些資料,可是我按了老半天,一直出現錯誤,迷迷糊糊地從那些文字中拼湊出一些單詞,只記得有什麼SQL Error,當時把這件事情跟客戶的會計反應,他旋即請了工程師過來處理,弄了一下之後跟我說需要明天才會好,要我明天再去撈

(範例,非當事錯誤)
後來這幾年工作上常常接觸到資料庫的東西,最近又想起這件事來,也總算知道當時遇到的錯誤是什麼了`我猜是IP連不到`。因此繼續趁著年假這個真的不知道做什麼事的時間點來科普一下ERP系統後面的東西,**SQL DataBase是什麼**?
# 什麼是SQL
首先要知道SQL怎麼發音,我都念SQL,但也有些人念SQL,SQL的念法是,`C闊(Ess-cue-ell')`。SQL這個詞的由來有人說沒意義,就是叫SQL,也有人認為是有意義的,也就是Structured Query Language(結構化查詢語言)的縮寫。簡而言之SQL就是用來跟資料庫(Database)溝通的一種Syntax(語法),SQL與資料庫的關係像魔法師與魔法書的關係,魔法師透過詠唱咒語(SQL語法)來使用魔法書(Database)的能力。
第一次接觸到SQL是在大四大三的時候吧,那時候好像有個系必修是什麼資訊概論類似的課程,老師上課的時候有提到一個東西,他的介面是隻海豚,然後有很多奇怪的按鈕,


當時的我完全不知道這些是啥,甚至連SQL是什麼都沒有半點頭緒,那門課我記得我只負責處理一些很瑣碎的事情,其他都靠我同學Carry過的XD。結果沒想到逃的了一時,逃不了一世,現在天天都會看到,感嘆命運多舛啊。
話說回來,所以什麼是SQL呢?他是用來做什麼的?我們首先先來講一下什麼是**關聯式資料庫**。大家應該有上過學吧,學校裡,有班級、有學生、有班導,有科任老師,這些東西都是互相有關聯的,比如說一個班導可以有很多學生,但每個學生只能有一個班導,一個科任老師也可以有很多學生,每個學生也可以有很多的科任老師。用來記錄這些資訊的資料庫就是所謂的關聯式資料庫`注:有關聯式就會有非關聯式資料庫,但這部分我就不熟了`。

(注:我事後回來看,我覺得這樣設計有很多問題,其實可以在精簡一點的,大佬就別鞭太大力了)
畫成關聯圖大概就是長這樣,原諒我畫的真的有點醜,不過大概看的出來它們彼此有哪些關係吧?學生跟班級、導師、科任老師有關聯、班級跟學生還有班導有關聯、班導跟科任老師沒有關聯(其實這邊設計的不太好,會違反資料正規化,但只是示範而已)。SQL Database我們每天都會碰到,比如說你每天上車逼的悠遊卡,你的卡號就被記在政府的悠遊卡SQL Database裡面,只要你遺失後,就會把你的那筆資料拉出來,標注已遺失。或是會計師考試報名時,會給你一組准考證號碼,所以考試院的SQL資料庫裏面,也會有這筆准考證的資料,這筆資料包含你的身分證、考試成績等等,只要涉及資料儲存的部分,其實背後都有資料庫的存在,也包含你的手機裡面的通訊錄等等,裡面都有小型的資料庫在裡面處理你的information。
# SQL的實作
多說無益,我們就用線上版的SQL編輯器來看看SQL是怎麼運作的吧,建議這邊點開我上面的HackMd,我有用Gif的方式錄影下來。
線上的SQL編輯器:https://sqliteonline.com/

點進去後會看到裡面長這個樣子,時間寶貴,我把左邊的欄位講一下就好,其實左邊就是各是各樣的SQL Database,不同的Database都有一些特性

+ SQLite:輕量化的SQL資料庫,常用於手機端。
+ MariaDB:MySQL的作者獨立出來開發的SQL資料庫
+ PostgreSQL:也是SQL資料庫
+ MSSQL:微軟開發的SQL資料庫,會有微軟的奧援
當然不只這些,像常聽到的Oracle,不只有做ERP系統,其實還有做SQL資料庫,當然Oracle做的不止這些。話說回來,這些語法都大同小異,但為了方便各位,我們這次就用SQLite做示範,因為這個頁面一點進來就是SQLite了。

這個紅色框框的地方就是讓我們打SQL語法的部分,我們先來創一些資料吧!秉持著能交給別人做的事情絕對不自己來的原則,這部分我們請ChatGPT來幫我們就好:)

ChatGPT產生的語法如上,這邊先講解一下會出現的名詞代表的意思,首先
+ Table:近似於Excel裡面的活頁表,每個活頁表都拿來描述不同的東西,比如說學生這張Table就是拿來存放跟學生有關的資料,比如說姓名、學號之類的東西。
+ DROP:近似於刪除
```sql
CREATE TABLE Student (
Name TEXT,
ClassTeacherName TEXT,
StudentID INTEGER,
ClassroomID INTEGER,
Birthdate DATE,
Subjects TEXT
);
```
這樣的語法代表創建一張名為Student的表格,裡面要有
- 名為Name的欄位,資料型別是文字
- 名為ClassTeacherName的欄位,資料型別是文字
- 名為StudentID的欄位,資料型別是數字
- 名為ClassroomID的欄位,資料型別是數字
- 名為Birthdate的欄位,資料型別是DATE(日期,亦即只能存放日期格式的東西)
- 名為Subjects的欄位,資料型別是文字
`資料型別代表這個欄位只能存什麼東西,如果資料型別是數字,就代表只能存在羅馬數字,如果輸入 天氣 就會出錯`
```sql
-- 如果已經存在這些表就刪除,確保每次都是產生全新的Table
DROP TABLE IF EXISTS demo;
DROP TABLE IF EXISTS Student;
DROP TABLE IF EXISTS Teacher;
DROP TABLE IF EXISTS Classroom;
DROP TABLE IF EXISTS SubjectTeacher;
-- Create Student table
CREATE TABLE Student (
Name TEXT,
ClassTeacherName TEXT,
StudentID INTEGER,
ClassroomID INTEGER,
Birthdate DATE,
Subjects TEXT
);
-- Create Teacher table
CREATE TABLE Teacher (
Name TEXT,
TeacherID INTEGER,
ClassroomID INTEGER
);
-- Create Classroom table
CREATE TABLE Classroom (
ClassroomID INTEGER,
ClassID INTEGER
);
-- Create SubjectTeacher table
CREATE TABLE SubjectTeacher (
Name TEXT,
TeacherID INTEGER,
Subject TEXT
);
```

完成後我們可以看到我們的左邊就出現很多的東西,就代表我們成功創建了Table喔!
但此時Table裡面的東西都是空的,我們試著塞一些資料進去Table裡面吧,這邊再次邀請我們的勞模ChatGPT

這邊的INSERT其實就是新增資料進去的意思。
```sql
-- Insert data into the Teacher table
INSERT INTO Teacher (Name, TeacherID, ClassroomID) VALUES ('John Smith', 1, 101);
INSERT INTO Teacher (Name, TeacherID, ClassroomID) VALUES ('Jane Doe', 2, 102);
INSERT INTO Teacher (Name, TeacherID, ClassroomID) VALUES ('Bob Johnson', 3, 103);
-- Insert data into the Classroom table
INSERT INTO Classroom (ClassroomID, ClassID) VALUES (101, 1);
INSERT INTO Classroom (ClassroomID, ClassID) VALUES (102, 2);
INSERT INTO Classroom (ClassroomID, ClassID) VALUES (103, 3);
-- Insert data into the SubjectTeacher table
INSERT INTO SubjectTeacher (Name, TeacherID, Subject) VALUES ('John Smith', 1, 'Math');
INSERT INTO SubjectTeacher (Name, TeacherID, Subject) VALUES ('Jane Doe', 2, 'Science');
INSERT INTO SubjectTeacher (Name, TeacherID, Subject) VALUES ('Bob Johnson', 3, 'English');
INSERT INTO SubjectTeacher (Name, TeacherID, Subject) VALUES ('Bob Johnson', 3, 'History');
-- Insert data into the Student table
INSERT INTO Student (Name, ClassTeacherName, StudentID, ClassroomID, Birthdate, Subjects) VALUES ('Alice Smith', 'John Smith', 1, 101, '2000-01-01', 'Math, Science');
INSERT INTO Student (Name, ClassTeacherName, StudentID, ClassroomID, Birthdate, Subjects) VALUES ('Bob Brown', 'John Smith', 2, 101, '2001-01-01', 'Math, English');
INSERT INTO Student (Name, ClassTeacherName, StudentID, ClassroomID, Birthdate, Subjects) VALUES ('Charlie Johnson', 'Jane Doe', 3, 102, '2002-01-01', 'Science, History');
INSERT INTO Student (Name, ClassTeacherName, StudentID, ClassroomID, Birthdate, Subjects) VALUES ('David Wilson', 'Jane Doe', 4, 102, '2003-01-01', 'Science, English');
INSERT INTO Student (Name, ClassTeacherName, StudentID, ClassroomID, Birthdate, Subjects) VALUES ('Eve Davis', 'Bob Johnson', 5, 103, '2004-01-01', 'English, History');
INSERT INTO Student (Name, ClassTeacherName, StudentID, ClassroomID, Birthdate, Subjects) VALUES ('Frank Miller', 'John Smith', 6, 101, '2005-01-01', 'Math');
INSERT INTO Student (Name, ClassTeacherName, StudentID, ClassroomID, Birthdate, Subjects) VALUES ('Gary Moore', 'Jane Doe', 7, 102, '2006-01-01', 'Science');
INSERT INTO Student (Name, ClassTeacherName, StudentID, ClassroomID, Birthdate, Subjects) VALUES ('Helen Anderson', 'Bob Johnson', 8, 103, '2007-01-01', 'English, History');
INSERT INTO Student (Name, ClassTeacherName, StudentID, ClassroomID, Birthdate, Subjects) VALUES ('Irene Thomas', 'John Smith', 9, 101, '2008-01-01', 'Math, Science');
INSERT INTO Student (Name, ClassTeacherName, StudentID, ClassroomID, Birthdate, Subjects) VALUES ('James Hernandez', 'Jane Doe', 10, 102, '2009-01-01', 'Science, English');
```

完成後,在Table上面點選右鍵,選擇SELECT即可這張表的所有屬性喔 !
+ 教室Table

+ 學生Table `這邊也違反資料庫正規化,一個應該只塞一筆資料的原則,我的subject塞了複數筆資料,但單純Demo而已,有點懶得改了`

+ 科任老師Table
+ 老師Table

# SQL語法的介紹
我們一樣在框框裡面操作
```sql
SELECT * FROM Teacher
```

這個語法的意思就是 SELECT`選擇` *`全部欄位` FROM`來自` Teacher`這張表`,翻成白話文的意思就是,幫我選出Teacher這張表的全部內容,當然我們也可以再複雜一點,比如說
```sql
SELECT * FROM Teacher WHERE teacherid = 2
```

也就是從Teacher這張表裡面選出TeacherId為2的欄位
```sql
SELECT * FROM Student WHERE subjects LIKE '%Math%'
```

當然我們再複雜一點點,這個語法會找出所有在Student這張Table裡面subjects欄位裡有Math的學生,聽起來有點繞口對吧XD,接著我們就把這些語法組合起來,試著找看看
```sql
SELECT Student.*
FROM Student
JOIN SubjectTeacher ON Student.ClassTeacherName = SubjectTeacher.Name
WHERE Birthdate BETWEEN '2001-01-01' AND '2005-12-31' AND SubjectTeacher.Subject = 'Math'
```

我們再複雜一點點點點,我們想找出所有在2001年至2005年出生,並且有修Math的學生,看到這邊這個語法大家是不是有點感覺了,是不是很像我們去撈資料常常用到的,要撈發生在本年度的100018應付帳款全部資料XD。其實背後的SQL語法就像這樣子。
當然實際上的情況SQL語法還會更複雜一點,因為這些這是關聯式資料庫,彼此間可能可以關聯到很遠很遠的Table,只是為了做科普而已就不弄得那麼複雜了。另外SQL Syntax(語法)也不只SELECT,常見的還有UPDATA, DELETE, CREATE等等,只是這些審計人員一般不會碰到。
# 結語
其實沒啥想講的,只是覺得很閒而已,想說趁年假時後把想寫的東西寫一寫,順便也當科普一樣,感覺會計這個圈子好像很少人在寫科普或是知識介紹的東西,就花個一兩個小時的時間寫一下,如果對SQL有興趣的話,可以去載來玩看看
+ MySQL:全英介面,一開始可能不太友好,但網路上資源最多
+ MSSQL:微軟的SQL,有中文介面,但網路上資源相對較少,其實SQL的語法都大同小異,但其實還是有一些不同處
+ PostgreSQL:通常不會用這個入門,我個人覺得它GUI的介面很爛,我用這個的話通常都是用Terminal
+ SQLite:不太推薦,因為這算是輕量化版的,有很多資料型別是特規的。
我文章常提到的資料庫正規化介紹如下
https://ithelp.ithome.com.tw/articles/10229472
忙季加油!債見