您好,登錄后才能下訂單哦!
SQL是什么?
SQL是結構化查詢語言,這是一種計算機語言,用于存儲,操縱和檢索存儲在關系數據庫中的數據。
SQL是關系數據庫系統的標準語言。所有關系型數據庫管理系統,如MySQL, MS Access, Oracle, Sybase, Informix, postgres 和SQL Server使用SQL作為標準數據庫語言。
此外,它們也使用不同的方言,如:
MS SQL Server 使用 T-SQL,
Oracle 使用 PL/SQL,
MS Access 的SQL版本叫 JET SQL (本地格式) 等
為什么使用SQL?
允許用戶訪問在關系數據庫管理系統的數據。
讓用戶來描述數據。
允許用戶定義數據庫中的數據和處理數據。
允許使用SQL模塊,庫和預編譯器的其他語言中嵌入。
允許用戶創建和刪除數據庫和表。
允許用戶創建視圖,存儲過程,函數在數據庫中。
允許用戶設置表,過程和視圖的權限
歷史:
1970 -- Dr. Edgar F. "Ted" IBM的科德被稱為關系數據庫之父,是他描述了數據庫的關系模型。
1974 -- 結構化查詢語言出現。
1978 -- IBM合作開發Codd的想法并發布了名為System/R的產品。
1986 -- IBM開發了關系型數據庫的第一臺樣機,并通過ANSI標準化。第一個關系型數據庫是由關系型軟件及其后來成為甲骨文發布。
SQL處理:
當你對任何RDBMS執行SQL命令,系統決定開展您的要求的最佳途徑和SQL引擎計算出如何解析任務。
有包括在過程中的各種組件。這些組件查詢調度,優化引擎,經典查詢引擎和SQL查詢引擎等等。經典查詢引擎處理所有非SQL查詢,但SQL查詢引擎不會處理邏輯文件。
以下是顯示SQL架構一個簡單的圖表:
標準的SQL命令進行互動使用在關系型數據庫有:CREATE, SELECT, INSERT, UPDATE, DELETE 和 DROP。這些命令可分為基于其性質組。
DDL - 數據定義語言
命令 | 描述 |
CREATE | 創建一個新的表,表的視圖,或者在數據庫中的對象 |
ALTER | 修改現有的數據庫對象,例如一個表 |
DROP | 刪除整個表,數據庫中的表或其他對象或視圖 |
DML - 數據操縱語言
命令 | 描述 |
SELECT | 從一個或多個表中檢索特定的記錄 |
INSERT | 創建記錄 |
UPDATE | 修改記錄 |
DELETE | 刪除記錄 |
DCL - 數據控制語言
命令 | 描述 |
GRANT | 授予用戶權限 |
REVOKE | 收回用戶授予的權限 |
MySQL數據類型
1、整型
MySQL數據類型 | 含義(有符號) |
tinyint(m) | 1個字節 范圍(-128~127) |
smallint(m) | 2個字節 范圍(-32768~32767) |
mediumint(m) | 3個字節 范圍(-8388608~8388607) |
int(m) | 4個字節 范圍(-2147483648~2147483647) |
bigint(m) | 8個字節 范圍(+-9.22*10的18次方) |
取值范圍如果加了unsigned,則最大值翻倍,如tinyint unsigned的取值范圍為(0~256)。
int(m)里的m是表示SELECT查詢結果集中的顯示寬度,并不影響實際的取值范圍,沒有影響到顯示的寬度,不知道這個m有什么用。
2、浮點型(float和double)
MySQL數據類型 | 含義 |
float(m,d) | 單精度浮點型 8位精度(4字節) m總個數,d小數位 |
double(m,d) | 雙精度浮點型 16位精度(8字節) m總個數,d小數位 |
設一個字段定義為float(5,3),如果插入一個數123.45678,實際數據庫里存的是123.457,但總個數還以實際為準,即6位。
3、定點數
浮點型在數據庫中存放的是近似值,而定點類型在數據庫中存放的是精確值。
decimal(m,d) 參數m<65 是總個數,d<30且 d<m 是小數位。
4、字符串(char,varchar,_text)
MySQL數據類型 | 含義 |
char(n) | 固定長度,最多255個字符 |
varchar(n) | 固定長度,最多65535個字符 |
tinytext | 可變長度,最多255個字符 |
text | 可變長度,最多65535個字符 |
mediumtext | 可變長度,最多2的24次方-1個字符 |
longtext | 可變長度,最多2的32次方-1個字符 |
char和varchar:
1.char(n) 若存入字符數小于n,則以空格補于其后,查詢之時再將空格去掉。所以char類型存儲的字符串末尾不能有空格,varchar不限于此。
2.char(n) 固定長度,char(4)不管是存入幾個字符,都將占用4個字節,varchar是存入的實際字符數+1個字節(n<=255)或2個字節(n>255),所以varchar(4),存入3個字符將占用4個字節。
3.char類型的字符串檢索速度要比varchar類型的快。
varchar和text:
1.varchar可指定n,text不能指定,內部存儲varchar是存入的實際字符數+1個字節(n<=255)或2個字節(n>255),text是實際字符數+2個字節。
2.text類型不能有默認值。
3.varchar可直接創建索引,text創建索引要指定前多少個字符。varchar查詢速度快于text,在都創建索引的情況下,text的索引似乎不起作用。
5.二進制數據(_Blob)
1._BLOB和_text存儲方式不同,_TEXT以文本方式存儲,英文存儲區分大小寫,而_Blob是以二進制方式存儲,不分大小寫。
2._BLOB存儲的數據只能整體讀出。
3._TEXT可以指定字符集,_BLO不用指定字符集。
6.日期時間類型
MySQL數據類型 | 含義 |
date | 日期 '2008-12-2' |
time | 時間 '12:25:36' |
datetime | 日期時間 '2008-12-2 22:06:44' |
timestamp | 自動存儲記錄修改時間 |
若定義一個字段為timestamp,這個字段里的時間數據會隨其他字段修改的時候自動刷新,所以這個數據類型的字段可以存放這條記錄最后被修改的時間。
數據類型的屬性
MySQL關鍵字 | 含義 |
NULL | 數據列可包含NULL值 |
NOT NULL | 數據列不允許包含NULL值 |
DEFAULT | 默認值 |
PRIMARY KEY | 主鍵 |
AUTO_INCREMENT | 自動遞增,適用于整數類型 |
UNSIGNED | 無符號 |
CHARACTER SET name | 指定一個字符集 |
創建數據庫
要在MySQL中創建數據庫,請使用CREATE DATABASE語句,如下:
CREATE DATABASE [IF NOT EXISTS] database_name;
我們來更詳細地看看CREATE DATABASE語句:
CREATE DATABASE語句的后面是要創建的數據庫名稱。建議數據庫名稱盡可能是有意義和具有一定的描述性。
IF NOT EXISTS是語句的可選子句。 IF NOT EXISTS子句可防止創建數據庫服務器中已存在的新數據庫的錯誤。不能在MySQL數據庫服務器中具有相同名稱的數據庫。
例如,要創建一個名稱為mytestdb數據庫,可以執行CREATE DATABASE語句后接數據庫名稱:mytestdb,如果當前MySQL服務器中沒有數據庫:mytestdb,則創建成功,如下所示:
CREATE DATABASE IF NOT EXISTS mytestdb;
執行此語句后,MySQL返回一條消息,通知新數據庫是否已成功創建。
顯示數據庫
SHOW DATABASES語句顯示MySQL數據庫服務器中的所有數據庫。您可以使用SHOW DATABASES語句來查看您要創建的數據庫,或者在創建新數據庫之前查看數據庫服務器上的所有數據庫,例如:
+--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | testdb | | yiibaidb | +--------------------+ 5 rows in set
在此MySQL數據庫服務器中有6個數據庫。 information_schema,performance_schema和mysql是我們安裝MySQL時可用的默認數據庫,而yiibaidb是創建的新數據庫。
選擇要使用的數據庫
在使用指定數據庫之前,必須通過使用USE語句告訴MySQL要使用哪個數據庫。
USE database_name;
您可以使用USE語句選擇示例數據庫(yiibaidb),如下所示:
USE yiibaidb;
從現在開始,所有操作(如查詢數據,創建新表或調用存儲過程)都將對當前數據庫(即yiibaidb)產生影響。
刪除數據庫
刪除數據庫意味著數據庫中的所有數據和關聯對象將被永久刪除,并且無法撤消。 因此,用額外的注意事項執行此查詢是非常重要的。
要刪除數據庫,請使用DROP DATABASE語句,如下所示:
DROP DATABASE [IF EXISTS] database_name;
遵循DROP DATABASE是要刪除的數據庫名稱。 與CREATE DATABASE語句類似,IF EXISTS是該語句的可選部分,以防止您刪除數據庫服務器中不存在的數據庫。
如果要使用DROP DATABASE語句練習,可以創建一個新數據庫,然后將其刪除。來看下面的查詢:
CREATE DATABASE IF NOT EXISTS tempdb; SHOW DATABASES; DROP DATABASE IF EXISTS tempdb;
三個語句的說明如下:
首先,使用CREATE DATABASE語句創建了一個名為tempdb的數據庫。
第二,使用SHOW DATABASES語句顯示所有數據庫。
第三,使用DROP DATABASE語句刪除了名為tempdb的數據庫。
MySQL CREATE TABLE語法
要在數據庫中創建一個新表,可以使用MySQL CREATE TABLE語句。 CREATE TABLE語句是MySQL中最復雜的語句之一。
下面以簡單的形式來說明CREATE TABLE語句的語法:
CREATE TABLE [IF NOT EXISTS] table_name( column_list ) engine=table_type;
我們來更詳細地來查看其語法:
首先,指定要在CREATE TABLE子句之后創建的表的名稱。表名在數據庫中必須是唯一的。 IF NOT EXISTS是語句的可選部分,允許您檢查正在創建的表是否已存在于數據庫中。 如果是這種情況,MySQL將忽略整個語句,不會創建任何新的表。 強烈建議在每個CREATE TABLE語句中使用IF NOT EXISTS來防止創建已存在的新表而產生錯誤。
其次,在column_list部分指定表的列表。字段的列用逗號(,)分隔。我們將在下一節中向您展示如何更詳細地列(字段)定義。
第三,需要為engine子句中的表指定存儲引擎。可以使用任何存儲引擎,如:InnoDB,MyISAM,HEAP,EXAMPLE,CSV,ARCHIVE,MERGE, FEDERATED或NDBCLUSTER。如果不明確聲明存儲引擎,MySQL將默認使用InnoDB。
注:InnoDB自MySQL 5.5之后成為默認存儲引擎。 InnoDB表類型帶來了諸如ACID事務,引用完整性和崩潰恢復等關系數據庫管理系統的諸多好處。在以前的版本中,MySQL使用MyISAM作為默認存儲引擎。
要在CREATE TABLE語句中為表定義列,請使用以下語法:
column_name data_type[size] [NOT NULL|NULL] [DEFAULT value] [AUTO_INCREMENT]
以上語法中最重要的組成部分是:
column_name指定列的名稱。每列具有特定數據類型和大小,例如:VARCHAR(255)。
NOT NULL或NULL表示該列是否接受NULL值。
DEFAULT值用于指定列的默認值。
AUTO_INCREMENT指示每當將新行插入到表中時,列的值會自動增加。每個表都有一個且只有一個AUTO_INCREMENT列。
如果要將表的特定列設置為主鍵,則使用以下語法:
PRIMARY KEY (col1,col2,...)
MySQL CREATE TABLE語句示例
下面讓我們練習一個例子,在示例數據庫(testdb)中創建一個名為tasks的新表,如下所示:
可以使用CREATE TABLE語句創建這個tasks表,如下所示:
CREATE TABLE IF NOT EXISTS tasks ( task_id INT(11) NOT NULL AUTO_INCREMENT, subject VARCHAR(45) DEFAULT NULL, start_date DATE DEFAULT NULL, end_date DATE DEFAULT NULL, description VARCHAR(200) DEFAULT NULL, PRIMARY KEY (task_id) ) ENGINE=InnoDB;
MySQL ALTER TABLE語句簡介
可以使用ALTER TABLE語句來更改現有表的結構。 ALTER TABLE語句可用來添加列,刪除列,更改列的數據類型,添加主鍵,重命名表等等。 以下說明了ALTER TABLE語句語法:
ALTER TABLE table_name action1[,action2,…]
要更改現有表的結構:
首先,在ALTER TABLE子句之后指定要更改的表名稱。
其次,列出一組要應用于該表的操作。操作可以是添加新列,添加主鍵,重命名表等任何操作。ALTER TABLE語句允許在單個ALTER TABLE語句中應用多個操作,每個操作由逗號(,)分隔。
讓我們創建一個用于練習ALTER TABLE語句的新表。
我們將在示例數據庫(yiibaidb)中創建一個名為tasks的新表。 以下是創建tasks表的腳本。
DROP TABLE IF EXISTS tasks; CREATE TABLE tasks ( task_id INT NOT NULL, subject VARCHAR(45) NULL, start_date DATE NULL, end_date DATE NULL, description VARCHAR(200) NULL, PRIMARY KEY (task_id), UNIQUE INDEX task_id_unique (task_id ASC) );
使用MySQL ALTER TABLE語句更改列
使用MySQL ALTER TABLE語句來設置列的自動遞增屬性
假設您希望在任務表中插入新行時,task_id列的值會自動增加1。那么可以使用ALTER TABLE語句將task_id列的屬性設置為AUTO_INCREMENT,如下所示:
ALTER TABLE tasks CHANGE COLUMN task_id task_id INT(11) NOT NULL AUTO_INCREMENT;
可以通過在tasks表中插入一些行數據來驗證更改。
INSERT INTO tasks(subject, start_date, end_date, description) VALUES('Learn MySQL ALTER TABLE', Now(), Now(), 'Practicing MySQL ALTER TABLE statement'); INSERT INTO tasks(subject, start_date, end_date, description) VALUES('Learn MySQL CREATE TABLE', Now(), Now(), 'Practicing MySQL CREATE TABLE statement');
您可以查詢數據以查看每次插入新行時task_id列的值是否增加1:
SELECT task_id, description FROM tasks;
使用MySQL ALTER TABLE語句將新的列添加到表中
由于新的業務需求,需要添加一個名為complete的新列,以便在任務表中存儲每個任務的完成百分比。 在這種情況下,您可以使用ALTER TABLE將新列添加到tasks表中,如下所示:
ALTER TABLE tasks ADD COLUMN complete DECIMAL(2,1) NULL AFTER description;
使用MySQL ALTER TABLE從表中刪除列
假設您不想將任務的描述存儲在tasks表中了,并且必須將其刪除。 以下語句允許您刪除tasks表的description列:
ALTER TABLE tasks DROP COLUMN description;
使用MySQL ALTER TABLE語句重命名表
可以使用ALTER TABLE語句重命名表。請注意,在重命名表之前,應該認真考慮以了解更改是否影響數據庫和應用程序層,不要因為重命名表之后,應用程序因未找到數據庫表而出錯。
以下語句將tasks表重命名為work_items表:
ALTER TABLE tasks RENAME TO work_items;
1.簡單的MySQL INSERT語句
MySQL INSERT語句允許您將一行或多行插入到表中。下面說明了INSERT語句的語法:
INSERT INTO table(column1,column2...) VALUES (value1,value2,...);
首先,在INSERT INTO子句之后,在括號內指定表名和逗號分隔列的列表。
然后,將括號內的相應列的逗號分隔值放在VALUES關鍵字之后。
在執行插入語句前,需要具有執行INSERT語句的INSERT權限。
讓我們創建一個名為tasks的新表來練習INSERT語句,參考以下創建語句 -
USE testdb; CREATE TABLE IF NOT EXISTS tasks ( task_id INT(11) AUTO_INCREMENT, subject VARCHAR(45) DEFAULT NULL, start_date DATE DEFAULT NULL, end_date DATE DEFAULT NULL, description VARCHAR(200) DEFAULT NULL, PRIMARY KEY (task_id) )ENGINE=InnoDB DEFAULT CHARSET=utf8;
例如,如果要將任務插入到tasts表中,則使用INSERT語句如下:
INSERT INTO tasks(subject,start_date,end_date,description) VALUES('Learn MySQL INSERT','2017-07-21','2017-07-22','Start learning..');
執行該語句后,MySQL返回一條消息以通知受影響的行數。 在這種情況下,有一行受到影響。
現在使用以下語句查詢 tasks 中的數據,如下所示 -
SELECT * FROM tasks;
執行上面查詢語句,得到以下結果
+---------+--------------------+------------+------------+------------------+ | task_id | subject | start_date | end_date | description | +---------+--------------------+------------+------------+------------------+ | 1 | Learn MySQL INSERT | 2017-07-21 | 2017-07-22 | Start learning.. | +---------+--------------------+------------+------------+------------------+ 1 row in set
2. MySQL INSERT - 插入多行
想要在表中一次插入多行,可以使用具有以下語法的INSERT語句:
INSERT INTO table(column1,column2...) VALUES (value1,value2,...), (value1,value2,...), ...;
在這種形式中,每行的值列表用逗號分隔。 例如,要將多行插入到tasks表中,請使用以下語句:
INSERT INTO tasks(subject,start_date,end_date,description) VALUES ('任務-1','2017-01-01','2017-01-02','Description 1'), ('任務-2','2017-01-01','2017-01-02','Description 2'), ('任務-3','2017-01-01','2017-01-02','Description 3');
執行上面語句后,返回
Query OK, 3 rows affected Records: 3 Duplicates: 0 Warnings: 0
現在查詢tasks表中的數據,如下所示
select * from tasks;
執行上面查詢語句,得到以下結果
如果為表中的所有列指定相應列的值,則可以忽略INSERT語句中的列列表,如下所示:
INSERT INTO table VALUES (value1,value2,...); 或者 INSERT INTO table VALUES (value1,value2,...), (value1,value2,...), ...;
請注意,不必為自動遞增列(例如taskid列)指定值,因為MySQL會自動為自動遞增列生成值。
3. 具有SELECT子句的MySQL INSERT
在MySQL中,可以使用SELECT語句返回的列和值來填充INSERT語句的值。 此功能非常方便,因為您可以使用INSERT和SELECT子句完全或部分復制表,如下所示:
INSERT INTO table_1 SELECT c1, c2, FROM table_2;
假設要將tasks表復制到tasks_bak表。
首先,通過復制tasks表的結構,創建一個名為tasks_bak的新表,如下所示:
CREATE TABLE tasks_bak LIKE tasks;
第二步,使用以下INSERT語句將tasks表中的數據插入tasks_bak表:
INSERT INTO tasks_bak SELECT * FROM tasks;
第三步,檢查tasks_bak表中的數據,看看是否真正從tasks表復制完成了。
mysql> select * from tasks; +---------+--------------------+------------+------------+------------------+ | task_id | subject | start_date | end_date | description | +---------+--------------------+------------+------------+------------------+ | 1 | Learn MySQL INSERT | 2017-07-21 | 2017-07-22 | Start learning.. | | 2 | 任務-1 | 2017-01-01 | 2017-01-02 | Description 1 | | 3 | 任務-2 | 2017-01-01 | 2017-01-02 | Description 2 | | 4 | 任務-3 | 2017-01-01 | 2017-01-02 | Description 3 | +---------+--------------------+------------+------------+------------------+ 4 rows in set
4. MySQL INSERT與ON DUPLICATE KEY UPDATE
如果新行違反主鍵(PRIMARY KEY)或UNIQUE約束,MySQL會發生錯誤。 例如,如果執行以下語句:
INSERT INTO tasks(task_id,subject,start_date,end_date,description) VALUES (4,'Test ON DUPLICATE KEY UPDATE','2017-01-01','2017-01-02','Next Priority');
MySQL很不高興,并向你扔來一個錯誤消息:
Error Code: 1062. Duplicate entry '4' for key 'PRIMARY' 0.016 sec
因為表中的主鍵task_id列已經有一個值為 4 的行了,所以該語句違反了PRIMARY KEY約束。
但是,如果在INSERT語句中指定ON DUPLICATE KEY UPDATE選項,MySQL將插入新行或使用新值更新原行記錄。
例如,以下語句使用新的task_id和subject來更新task_id為4的行。
INSERT INTO tasks(task_id,subject,start_date,end_date,description) VALUES (4,'Test ON DUPLICATE KEY UPDATE','2017-01-01','2017-01-02','Next Priority') ON DUPLICATE KEY UPDATE task_id = task_id + 1, subject = 'Test ON DUPLICATE KEY UPDATE';
執行上面語句后,MySQL發出消息說2行受影響。現在,我們來看看tasks表中的數據:
mysql> select * from tasks; +---------+------------------------------+------------+------------+------------------+ | task_id | subject | start_date | end_date | description | +---------+------------------------------+------------+------------+------------------+ | 1 | Learn MySQL INSERT | 2017-07-21 | 2017-07-22 | Start learning.. | | 2 | 任務-1 | 2017-01-01 | 2017-01-02 | Description 1 | | 3 | 任務-2 | 2017-01-01 | 2017-01-02 | Description 2 | | 5 | Test ON DUPLICATE KEY UPDATE | 2017-01-01 | 2017-01-02 | Description 3 | +---------+------------------------------+------------+------------+------------------+ 4 rows in set
新行沒有被插入,但是更新了task_id值為4的行。上面的INSERT ON DUPLICATE KEY UPDATE語句等效于以下UPDATE語句:
UPDATE tasks SET task_id = task_id + 1, subject = 'Test ON DUPLICATE KEY UPDATE' WHERE task_id = 4;
修改表數據
1. MySQL UPDATE語句簡介
我們使用UPDATE語句來更新表中的現有數據。也可以使用UPDATE語句來更改表中單個行,一組行或所有行的列值。
下面說明了MySQL UPDATE語句的語法:
UPDATE [LOW_PRIORITY] [IGNORE] table_name SET column_name1 = expr1, column_name2 = expr2, ... WHERE condition;
在上面UPDATE語句中:
首先,在UPDATE關鍵字后面指定要更新數據的表名。
其次,SET子句指定要修改的列和新值。要更新多個列,請使用以逗號分隔的列表。以字面值,表達式或子查詢的形式在每列的賦值中來提供要設置的值。
第三,使用WHERE子句中的條件指定要更新的行。WHERE子句是可選的。 如果省略WHERE子句,則UPDATE語句將更新表中的所有行。
請注意,WHERE子句非常重要,所以不應該忘記指定更新的條件。 有時,您可能只想改變一行; 但是,可能會忘記寫上WHERE子句,導致意外更新表中的所有行。
MySQL在UPDATE語句中支持兩個修飾符。
LOW_PRIORITY修飾符指示UPDATE語句延遲更新,直到沒有從表中讀取數據的連接。 LOW_PRIORITY對僅使用表級鎖定的存儲引擎(例如MyISAM,MERGE,MEMORY)生效。
即使發生錯誤,IGNORE修飾符也可以使UPDATE語句繼續更新行。導致錯誤(如重復鍵沖突)的行不會更新。
2. MySQL UPDATE示例
我們使用MySQL示例數據庫(yiibaidb)中的一些表來練習使用UPDATE語句。
2.1 MySQL UPDATE一個單列示例
在這個例子中,我們將把 Mary Patterson 的電子郵件更新為新的電子郵件mary.patterso@yiibai.com。
首先,為了確保更新電子郵件成功,使用以下SELECT語句從employees表查詢Mary的電子郵件:
SELECT firstname, lastname, email FROM employees WHERE employeeNumber = 1056;
執行上面的查詢語句,得到以下結果
+-----------+-----------+----------------------+ | firstname | lastname | email | +-----------+-----------+----------------------+ | Mary | Patterson | mpatterso@yiibai.com | +-----------+-----------+----------------------+ 1 row in set
第二步,使用UPDATE語句將Mary的電子郵件更新為新的電子郵件:mary.new@yiibai.com,如下查詢所示:
UPDATE employees SET email = 'mary.new@yiibai.com' WHERE employeeNumber = 1056;
因為上面語句中,只想更新一行,所以使用WHERE子句來指定更新的是員工編號1056的行。SET子句將電子郵件列的值設置為新的電子郵件。
第三,再次執行SELECT語句來驗證更改。
SELECT firstname, lastname, email FROM employees WHERE employeeNumber = 1056;
再次執行上面的查詢語句,得到以下結果
+-----------+-----------+---------------------+ | firstname | lastname | email | +-----------+-----------+---------------------+ | Mary | Patterson | mary.new@yiibai.com | +-----------+-----------+---------------------+ 1 row in set
2.2 MySQL UPDATE多列
要更新多列中的值,需要在SET子句中指定分配。例如,以下語句更新了員工編號1056的姓氏和電子郵件列:
UPDATE employees SET lastname = 'Hill', email = 'mary.hill@yiibai.com' WHERE employeeNumber = 1056;
在執行上面語句之后,查詢員工編號為:1056的記錄,如下所示 -
+-----------+----------+----------------------+ | firstname | lastname | email | +-----------+----------+----------------------+ | Mary | Hill | mary.hill@yiibai.com | +-----------+----------+----------------------+ 1 row in set
2.3 使用SELECT語句的MySQL UPDATE示例
可以使用SELECT語句查詢來自其他表的數據來提供給SET子句的值。
例如,在customers表中,有些客戶沒有任何銷售代表。 salesRepEmployeeNumber列的值為NULL,如下所示:
mysql> SELECT customername, salesRepEmployeeNumber FROM customers WHERE salesRepEmployeeNumber IS NULL; +--------------------------------+------------------------+ | customername | salesRepEmployeeNumber | +--------------------------------+------------------------+ | Havel & Zbyszek Co | NULL | | Porto Imports Co. | NULL | | Asian Shopping Network, Co | NULL | | Natrlich Autos | NULL | | ANG Resellers | NULL | | Messner Shopping Network | NULL | | Franken Gifts, Co | NULL | | BG&E Collectables | NULL | | Schuyler Imports | NULL | | Der Hund Imports | NULL | | Cramer Spezialitten, Ltd | NULL | | Asian Treasures, Inc. | NULL | | SAR Distributors, Co | NULL | | Kommission Auto | NULL | | Lisboa Souveniers, Inc | NULL | | Stuttgart Collectable Exchange | NULL | | Feuer Online Stores, Inc | NULL | | Warburg Exchange | NULL | | Anton Designs, Ltd. | NULL | | Mit Vergngen & Co. | NULL | | Kremlin Collectables, Co. | NULL | | Raanan Stores, Inc | NULL | +--------------------------------+------------------------+ 22 rows in set
我們可以為這些客戶提供銷售代表和更新。
為此,需要從employees表中隨機選擇一個職位為Sales Rep的雇員,并將其更新到employees表中。
下面的查詢語句是從employees表中隨機選擇一個其職位是Sales Rep的員工。
SELECT employeeNumber FROM employees WHERE jobtitle = 'Sales Rep' ORDER BY RAND() LIMIT 1;
要更新customers表中的銷售代表員工編號(employeeNumber)列,我們將上面的查詢放在UPDATE語句的SET子句中,如下所示:
UPDATE customers SET salesRepEmployeeNumber = (SELECT employeeNumber FROM employees WHERE jobtitle = 'Sales Rep' LIMIT 1) WHERE salesRepEmployeeNumber IS NULL;
如果在執行上面更新語句后,查詢employees表中的數據,將看到每個客戶都有一個銷售代表。 換句話說,以下查詢不返回任何行數據。
SELECT salesRepEmployeeNumber FROM customers WHERE salesRepEmployeeNumber IS NULL;
刪除表數據
1. MySQL DELETE語句介紹
要從表中刪除數據,請使用MySQL DELETE語句。下面說明了DELETE語句的語法:
DELETE FROM table_name WHERE condition;
在上面查詢語句中
首先,指定刪除數據的表(table_name)。
其次,使用條件來指定要在WHERE子句中刪除的行記錄。如果行匹配條件,這些行記錄將被刪除。
請注意,WHERE子句是可選的。如果省略WHERE子句,DELETE語句將刪除表中的所有行。
除了從表中刪除數據外,DELETE語句返回刪除的行數。
要使用單個DELETE語句從多個表中刪除數據,請閱讀下一個教程中將介紹的DELETE JOIN語句。
要刪除表中的所有行,而不需要知道刪除了多少行,那么應該使用TRUNCATE TABLE語句來獲得更好的執行性能。
對于具有外鍵約束的表,當從父表中刪除行記錄時,子表中的行記錄將通過使用ON DELETE CASCADE選項自動刪除。
2. MySQL DELETE的例子
我們將使用示例數據庫(yiibaidb)中的employees表進行演示。
+-------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+--------------+------+-----+---------+----------------+ | emp_id | int(11) | NO | PRI | NULL | auto_increment | | emp_name | varchar(255) | NO | | NULL | | | performance | int(11) | YES | MUL | NULL | | | salary | float | YES | | NULL | | +-------------+--------------+------+-----+---------+----------------+ 4 rows in set
請注意,一旦刪除數據,它就會永遠消失。 因此,在執行DELETE語句之前,應該先備份數據庫,以防萬一要找回刪除過的數據。
假設要刪除officeNumber為4的員工,則使用DELETE語句與WHERE子句作為以下查詢:
DELETE FROM employees WHERE officeCode = 4;
要刪除employees表中的所有行,請使用不帶WHERE子句的DELETE語句,如下所示:
DELETE FROM employees;
在執行上面查詢語句后,employees表中的所有行都被刪除。
MySQL DELETE和LIMIT子句
如果要限制要刪除的行數,則使用LIMIT子句,如下所示:
DELETE FROM table LIMIT row_count;
請注意,表中的行順序未指定,因此,當您使用LIMIT子句時,應始終使用ORDER BY子句,不然刪除的記錄可能不是你所預期的那樣。
DELETE FROM table_name ORDER BY c1, c2, ... LIMIT row_count;
考慮在示例數據庫(yiibaidb)中的customers表,其表結構如下:
mysql> desc customers; +------------------------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------------------+---------------+------+-----+---------+-------+ | customerNumber | int(11) | NO | PRI | NULL | | | customerName | varchar(50) | NO | | NULL | | | contactLastName | varchar(50) | NO | | NULL | | | contactFirstName | varchar(50) | NO | | NULL | | | phone | varchar(50) | NO | | NULL | | | addressLine1 | varchar(50) | NO | | NULL | | | addressLine2 | varchar(50) | YES | | NULL | | | city | varchar(50) | NO | | NULL | | | state | varchar(50) | YES | | NULL | | | postalCode | varchar(15) | YES | | NULL | | | country | varchar(50) | NO | | NULL | | | salesRepEmployeeNumber | int(11) | YES | MUL | NULL | | | creditLimit | decimal(10,2) | YES | | NULL | | +------------------------+---------------+------+-----+---------+-------+ 13 rows in set
例如,以下語句按客戶名稱按字母排序客戶,并刪除前10個客戶:
DELETE FROM customers ORDER BY customerName LIMIT 10;
類似地,以下DELETE語句選擇法國(France)的客戶,按升序按信用額度(creditLimit)進行排序,并刪除前5個客戶:
DELETE FROM customers WHERE country = 'France' ORDER BY creditLimit LIMIT 5;
類似地,以下DELETE語句選擇法國(France)的客戶,按升序按信用額度(creditLimit)進行排序,并刪除前5個客戶:
DELETE FROM customers WHERE country = 'France' ORDER BY creditLimit LIMIT 5;
查詢表記錄(select)
查詢語法:
SELECT *|field1,filed2 ... FROM tab_name WHERE 條件 GROUP BY field HAVING 篩選 ORDER BY field LIMIT 限制條數 Mysql在執行sql語句時的執行順序: -- from where select group by having order by
準備數據
CREATE TABLE emp( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20), gender ENUM("male","female","other"), age TINYINT, dep VARCHAR(20), city VARCHAR(20), salary DOUBLE(7,2) ); INSERT INTO emp (name,gender,age,dep,city,salary) VALUES ("yuan","male",24,"教學部","河北省",8000), ("egon","male",34,"保安部","山東省",8000), ("alex","male",28,"×××部","山東省",10000), ("景麗陽","female",22,"教學部","北京",9000), ("張三", "male",24,"教學部","河北省",6000), ("李四", "male",32,"保安部","北京",12000), ("王五", "male",38,"教學部","河北省",7000), ("趙六", "male",19,"保安部","河北省",9000), ("豬七", "female",24,"×××部","北京",9000); SELECT * FROM emp;
mysql> SELECT * FROM emp; +----+-----------+--------+------+-----------+-----------+----------+ | id | name | gender | age | dep | city | salary | +----+-----------+--------+------+-----------+-----------+----------+ | 1 | yuan | male | 24 | 教學部 | 河北省 | 8000.00 | | 2 | egon | male | 34 | 保安部 | 山東省 | 8000.00 | | 3 | alex | male | 28 | ×××部 | 山東省 | 10000.00 | | 4 | 景麗陽 | female | 22 | 教學部 | 北京 | 9000.00 | | 5 | 張三 | male | 24 | 教學部 | 河北省 | 6000.00 | | 6 | 李四 | male | 32 | 保安部 | 北京 | 12000.00 | | 7 | 王五 | male | 38 | 教學部 | 河北省 | 7000.00 | | 8 | 趙六 | male | 19 | 保安部 | 河北省 | 9000.00 | | 9 | 豬七 | female | 24 | ×××部 | 北京 | 9000.00 | +----+-----------+--------+------+-----------+-----------+----------+ rows in set (0.00 sec)
where子句: 過濾查詢
where字句中可以使用 比較運算符: > < >= <= <> != between 80 and 100 值在10到20之間 in(80,90,100) 值是10或20或30 like 'yuan%' /* pattern可以是%或者_, 如果是%則表示任意多字符,此例如唐僧,唐國強 如果是_則表示一個字符唐_,只有唐僧符合。兩個_則表示兩個字符:__ */ 邏輯運算符 在多個條件直接可以使用邏輯運算符 and or not
查詢年紀大于24的員工
SELECT * FROM emp WHERE age>24;
查詢教學部的男老師信息
SELECT * FROM emp WHERE dep="教學部" AND gender="male";
order:排序
按指定的列進行,排序的列即可是表中的列名,也可以是select語句后指定的別名。
語法:
select *|field1,field2... from tab_name order by field [Asc|Desc]
Asc 升序、Desc 降序,其中asc為默認值 ORDER BY 子句應位于SELECT語句的結尾。
示例:
按年齡從高到低進行排序
SELECT * FROM emp ORDER BY age DESC ;
按工資從低到高進行排序
SELECT * FROM emp ORDER BY salary;
group by:分組查詢(*****)
GROUP BY 語句根據某個列對結果集進行分組。在分組的列上我們可以使用 COUNT, SUM, AVG等函數進行相關查詢。
語法:
SELECT column_name, function(column_name) FROM table_name WHERE column_name operator value GROUP BY column_name;
示例:
-- 查詢男女員工各有多少人
SELECT gender 性別,count(*) 人數 FROM emp5 GROUP BY gender;
-- 查詢各個部門的人數
SELECT dep 部門,count(*) 人數 FROM emp5 GROUP BY dep;
-- 查詢每個部門最大的年齡
SELECT dep 部門,max(age) 最大年紀 FROM emp5 GROUP BY dep;
-- 查詢每個部門年齡最大的員工姓名
SELECT * FROM emp5 WHERE age in (SELECT max(age) FROM emp5 GROUP BY dep);
-- 查詢每個部門的平均工資
SELECT dep 部門,avg(salary) 最大年紀 FROM emp GROUP BY dep;
-- 查詢教學部的員工最高工資:
SELECT dep,max(salary) FROM emp11 GROUP BY dep HAVING dep="教學部";
-- 查詢平均薪水超過8000的部門
SELECT dep,AVG(salary) FROM emp GROUP BY dep HAVING avg(salary)>8000;
-- 查詢每個組的員工姓名
SELECT dep,group_concat(name) FROM emp GROUP BY dep;
-- 查詢公司一共有多少員工(可以將所有記錄看成一個組)
SELECT COUNT(*) 員工總人數 FROM emp;
-- KEY: 查詢條件中的每個后的詞就是分組的字段
limit記錄條數限制
SELECT * from ExamResult limit 1; SELECT * from ExamResult limit 2,5; -- 跳過前兩條顯示接下來的五條紀錄 SELECT * from ExamResult limit 2,2;
正則表達式
SELECT * FROM employee WHERE emp_name REGEXP '^yu'; SELECT * FROM employee WHERE emp_name REGEXP 'yun$'; SELECT * FROM employee WHERE emp_name REGEXP 'm{2}';
多表查詢
創建表
CREATE TABLE emp( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20), salary DOUBLE(7,2), dep_id INT ); INSERT INTO emp (name,salary,dep_id) VALUES ("張三",8000,2), ("李四",12000,1), ("王五",5000,2), ("趙六",8000,3), ("豬七",9000,1), ("周八",7000,4), ("蔡九",7000,2); CREATE TABLE dep( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20) ); INSERT INTO dep (name) VALUES ("教學部"), ("銷售部"), ("人事部");
mysql> select * from emp;
+----+--------+----------+--------+
| id | name | salary | dep_id |
+----+--------+----------+--------+
| 1 | 張三 | 8000.00 | 2 |
| 2 | 李四 | 12000.00 | 1 |
| 3 | 王五 | 5000.00 | 2 |
| 4 | 趙六 | 8000.00 | 3 |
| 5 | 豬七 | 9000.00 | 1 |
| 6 | 周八 | 7000.00 | 4 |
| 7 | 蔡九 | 7000.00 | 2 |
+----+--------+----------+--------+
7 rows in set (0.00 sec)
mysql> select * from dep;
+----+-----------+
| id | name |
+----+-----------+
| 1 | 教學部 |
| 2 | 銷售部 |
| 3 | 人事部 |
+----+-----------+
3 rows in set (0.00 sec)
1.笛卡爾積查詢
select * from emp,dep;
mysql> select * from emp,dep;
+----+--------+----------+--------+----+-----------+
| id | name | salary | dep_id | id | name |
+----+--------+----------+--------+----+-----------+
| 1 | 張三 | 8000.00 | 2 | 1 | 教學部 |
| 1 | 張三 | 8000.00 | 2 | 2 | 銷售部 |
| 1 | 張三 | 8000.00 | 2 | 3 | 人事部 |
| 2 | 李四 | 12000.00 | 1 | 1 | 教學部 |
| 2 | 李四 | 12000.00 | 1 | 2 | 銷售部 |
| 2 | 李四 | 12000.00 | 1 | 3 | 人事部 |
| 3 | 王五 | 5000.00 | 2 | 1 | 教學部 |
| 3 | 王五 | 5000.00 | 2 | 2 | 銷售部 |
| 3 | 王五 | 5000.00 | 2 | 3 | 人事部 |
| 4 | 趙六 | 8000.00 | 3 | 1 | 教學部 |
| 4 | 趙六 | 8000.00 | 3 | 2 | 銷售部 |
| 4 | 趙六 | 8000.00 | 3 | 3 | 人事部 |
| 5 | 豬七 | 9000.00 | 1 | 1 | 教學部 |
| 5 | 豬七 | 9000.00 | 1 | 2 | 銷售部 |
| 5 | 豬七 | 9000.00 | 1 | 3 | 人事部 |
| 6 | 周八 | 7000.00 | 4 | 1 | 教學部 |
| 6 | 周八 | 7000.00 | 4 | 2 | 銷售部 |
| 6 | 周八 | 7000.00 | 4 | 3 | 人事部 |
| 7 | 蔡九 | 7000.00 | 2 | 1 | 教學部 |
| 7 | 蔡九 | 7000.00 | 2 | 2 | 銷售部 |
| 7 | 蔡九 | 7000.00 | 2 | 3 | 人事部 |
+----+--------+----------+--------+----+-----------+
21 rows in set (0.00 sec)
2、內連接
查詢兩張表中都有的關聯數據,相當于利用條件從笛卡爾積結果中篩選出了正確的結果。
SELECT * FROM emp,dep WHERE emp.dep_id=dep.id;
OR
SELECT * FROM emp INNER JOIN dep ON emp.dep_id=dep.id;
查詢結果:
+----+--------+----------+--------+----+-----------+
| id | name | salary | dep_id | id | name |
+----+--------+----------+--------+----+-----------+
| 1 | 張三 | 8000.00 | 2 | 2 | 銷售部 |
| 2 | 李四 | 12000.00 | 1 | 1 | 教學部 |
| 3 | 王五 | 5000.00 | 2 | 2 | 銷售部 |
| 4 | 趙六 | 8000.00 | 3 | 3 | 人事部 |
| 5 | 豬七 | 9000.00 | 1 | 1 | 教學部 |
| 7 | 蔡九 | 7000.00 | 2 | 2 | 銷售部 |
+----+--------+----------+--------+----+-----------+
6 rows in set (0.00 sec)
這時,我們就可以利用兩張表中所有的字段進行查詢了
示例:
-- 查詢李四所在的部門名稱
SELECT emp.name,dep.name FROM emp INNER JOIN dep ON emp.dep_id=dep.id WHERE emp.name="李四";
-- 查詢銷售部所有員工姓名以及部門名稱
-- SELECT name FROM emp WHERE dep_id in (SELECT id FROM dep WHERE name="銷售部");
SELECT emp.name,dep.name FROM emp INNER JOIN dep ON emp.dep_id=dep.id WHERE dep.name="銷售部";
3、外連接
(1)左外連接:在內連接的基礎上增加左邊有右邊沒有的結果
SELECT * FROM emp LEFT JOIN dep ON dep.id=emp.dep_id;
+----+--------+----------+--------+------+-----------+
| id | name | salary | dep_id | id | name |
+----+--------+----------+--------+------+-----------+
| 2 | 李四 | 12000.00 | 1 | 1 | 教學部 |
| 5 | 豬七 | 9000.00 | 1 | 1 | 教學部 |
| 1 | 張三 | 8000.00 | 2 | 2 | 銷售部 |
| 3 | 王五 | 5000.00 | 2 | 2 | 銷售部 |
| 7 | 蔡九 | 7000.00 | 2 | 2 | 銷售部 |
| 4 | 趙六 | 8000.00 | 3 | 3 | 人事部 |
| 6 | 周八 | 7000.00 | 4 | NULL | NULL |
+----+--------+----------+--------+------+-----------+
7 rows in set (0.00 sec)
(1)外右連接:在內連接的基礎上增加右邊有左邊沒有的結果
SELECT * FROM emp RIGHT JOIN dep ON dep.id=emp.dep_id;
mysql> SELECT * FROM emp RIGHT JOIN dep ON dep.id=emp.dep_id;
+------+--------+----------+--------+----+-----------+
| id | name | salary | dep_id | id | name |
+------+--------+----------+--------+----+-----------+
| 1 | 張三 | 8000.00 | 2 | 2 | 銷售部 |
| 2 | 李四 | 12000.00 | 1 | 1 | 教學部 |
| 3 | 王五 | 5000.00 | 2 | 2 | 銷售部 |
| 4 | 趙六 | 8000.00 | 3 | 3 | 人事部 |
| 5 | 豬七 | 9000.00 | 1 | 1 | 教學部 |
| 7 | 蔡九 | 7000.00 | 2 | 2 | 銷售部 |
+------+--------+----------+--------+----+-----------+
6 rows in set (0.00 sec)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。