操作MySQL數據庫

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命令

標準的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 的電子郵件更新爲新的電子郵件[email protected]

首先,爲了確保更新電子郵件成功,使用以下SELECT語句從employees表查詢Mary的電子郵件:

SELECT 
    firstname, lastname, email
FROM
    employees
WHERE
    employeeNumber = 1056;

執行上面的查詢語句,得到以下結果

+-----------+-----------+----------------------+
| firstname | lastname  | email                |
+-----------+-----------+----------------------+
| Mary      | Patterson | [email protected] |
+-----------+-----------+----------------------+
1 row in set

第二步,使用UPDATE語句將Mary的電子郵件更新爲新的電子郵件:[email protected],如下查詢所示:

UPDATE employees 
SET 
    email = '[email protected]'
WHERE
    employeeNumber = 1056;

因爲上面語句中,只想更新一行,所以使用WHERE子句來指定更新的是員工編號1056的行。SET子句將電子郵件列的值設置爲新的電子郵件。

第三,再次執行SELECT語句來驗證更改。

SELECT 
    firstname, lastname, email
FROM
    employees
WHERE
    employeeNumber = 1056;

再次執行上面的查詢語句,得到以下結果

+-----------+-----------+---------------------+
| firstname | lastname  | email               |
+-----------+-----------+---------------------+
| Mary      | Patterson | [email protected] |
+-----------+-----------+---------------------+
1 row in set

2.2 MySQL UPDATE多列

要更新多列中的值,需要在SET子句中指定分配。例如,以下語句更新了員工編號1056的姓氏和電子郵件列:

UPDATE employees 
SET 
    lastname = 'Hill',
    email = '[email protected]'
WHERE
    employeeNumber = 1056;

在執行上面語句之後,查詢員工編號爲:1056的記錄,如下所示 -

+-----------+----------+----------------------+
| firstname | lastname | email                |
+-----------+----------+----------------------+
| Mary      | Hill     | [email protected] |
+-----------+----------+----------------------+
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)


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