1. 程式人生 > 實用技巧 >mysql記錄操作

mysql記錄操作

一介紹

MySQL資料操作: DML

========================================================

在MySQL管理軟體中,可以通過SQL語句中的DML語言來實現資料的操作,包括

  1. 使用INSERT實現資料的插入
  2. UPDATE實現資料的更新
  3. 使用DELETE實現資料的刪除
  4. 使用SELECT查詢資料以及。

*========================================================*

二 插入資料INSERT

1. 插入完整資料(順序插入)
    語法一:
    INSERT INTO 表名(欄位1,欄位2,欄位3…欄位n) VALUES(值1,值2,值3…值n);

    語法二:
    INSERT INTO 表名 VALUES (值1,值2,值3…值n);

2. 指定欄位插入資料
    語法:
    INSERT INTO 表名(欄位1,欄位2,欄位3…) VALUES (值1,值2,值3…);

3. 插入多條記錄
    語法:
    INSERT INTO 表名 VALUES
        (值1,值2,值3…值n),
        (值1,值2,值3…值n),
        (值1,值2,值3…值n);
        
4. 插入查詢結果
    語法:
    INSERT INTO 表名(欄位1,欄位2,欄位3…欄位n) 
                    SELECT (欄位1,欄位2,欄位3…欄位n) FROM 表2
                    WHERE …;

三 更新資料UPDATE

語法:
    UPDATE 表名 SET
        欄位1=值1,
        欄位2=值2,
        WHERE CONDITION;

示例:
    UPDATE mysql.user SET password=password(‘123’) 
        where user=’root’ and host=’localhost’;

四 刪除資料DELETE

語法:
    DELETE FROM 表名 
        WHERE CONITION;

示例:
    DELETE FROM mysql.user 
        WHERE password=’’;

練習:
    更新MySQL root使用者密碼為mysql123
    刪除除從本地登入的root使用者以外的所有使用者

五 查詢資料SELECT

1.單表查詢的語法

SELECT 欄位1,欄位2... FROM 表名
                  WHERE 條件
                  GROUP BY field
                  HAVING 篩選
                  ORDER BY field
                  LIMIT 限制條數

2.關鍵字的執行優先順序(重點)

1.找到表:from
2.拿到where指定的約束條件,去檔案/表中取出一條條記錄
3.將取出的一條條記錄進行分組group by,如果沒有group by,則整體做為一組
4.將分組的結果進行having過濾
5.執行select
6.去重
7.將結果按條件排序:order by
8.限制結果的顯示條數

3.簡單查詢

company.employee
	  員工id      id                  int             
    姓名        emp_name            varchar
    性別        sex                 enum
    年齡        age                 int
    崗位        post                varchar
    薪水        salary              double

create table emp(
id int primary key auto_increment,
name varchar(10) not null,
sex enum('male','female') not null default 'male',
age int(3) unsigned not null,
hire_date date not null,
post varchar(10),
salary int
);

#查看錶的結構
mysql> desc emp;
+--------+----------------------+------+-----+---------+----------------+
| Field  | Type                 | Null | Key | Default | Extra          |
+--------+----------------------+------+-----+---------+----------------+
| id     | int(11)              | NO   | PRI | NULL    | auto_increment |
| name   | varchar(10)          | NO   |     | NULL    |                |
| sex    | enum('male','femle') | NO   |     | male    |                |
| age    | int(3) unsigned      | NO   |     | NULL    |                |
| post   | varchar(10)          | YES  |     | NULL    |                |
| salary | int(11)              | YES  |     | NULL    |                |
+--------+----------------------+------+-----+---------+----------------+

#插入記錄
insert emp(name,sex,age,hire_date,post,salary) values
('alex','male',78,'20150302','teacher',1000000),
('wupeiqi','male',81,'20130305','teacher',8300),
('yuanhao','male',73,'20140701','teacher',3500),
('liwenzhou','male',28,'20121101','teacher',2100),
('yy','female',48,'20150311','sale',3000),
('dd','female',38,'20101101','sale',2000),
('mm','female',18,'20110312','sale',1000),
('arther','male',28,'20160311','operation',10000),
('egon','male',18,'19970312','operation',20000),
('tank','female',18,'20130311','operation',19000),
('gg','male',18,'20150411','operation',18000);

#簡單查詢

=====檢視全部=====
select * from emp;
=====檢視指定欄位下的記錄=====
select name,sarlary from emp;

#避免重複distinct
select distinct post from emp; 

#通過四則運算查詢
select name,salary*12 from emp;
select name,salary*12 as year_salary from emp;
為新的記錄取欄位名,不然會預設salary*12為欄位

#定義顯示格式
concat() 函式用於連線字串
select concat()
select concat('nick_name: ',name,'   year_salary: ', salary*12)  as annual_salary 
from emp;
+-------------------------------------------+
| annual_salary                             |
+-------------------------------------------+
| nick_name: alex   year_salary: 12000000   |
| nick_name: wupeiqi   year_salary: 99600   |
| nick_name: yuanhao   year_salary: 42000   |
| nick_name: liwenzhou   year_salary: 25200 |
| nick_name: yy   year_salary: 36000        |
| nick_name: dd   year_salary: 24000        |
| nick_name: mm   year_salary: 12000        |
| nick_name: arther   year_salary: 120000   |
| nick_name: egon   year_salary: 240000     |
| nick_name: tank   year_salary: 228000     |
| nick_name: gg   year_salary: 216000       |
+-------------------------------------------+
合併字串並且成為新的記錄在annual_salary欄位下

concat_ws() 第一個引數為分隔符
select concat_ws(':',name,salary*12) as year_sarlary from emp;
+-----------------+
| year_sarlary    |
+-----------------+
| alex:12000000   |
| wupeiqi:99600   |
| yuanhao:42000   |
| liwenzhou:25200 |
| yy:36000        |
| dd:24000        |
| mm:12000        |
| arther:120000   |
| egon:240000     |
| tank:228000     |
| gg:216000       |
+-----------------+

結合case語句
select(case when name='egon' then name when name='alex' then concat(name,'_bigsb')
else concat(name,'_sb') end) as new_name from emp;
+--------------+
| new_name     |
+--------------+
| alex_bigsb   |
| wupeiqi_sb   |
| yuanhao_sb   |
| liwenzhou_sb |
| yy_sb        |
| dd_sb        |
| mm_sb        |
| arther_sb    |
| egon         |
| tank_sb      |
| gg_sb        |
+--------------+

小練習:

1.查出所有員工的名字,薪資,格式為<名字:egon>    <薪資:3000>
select concat('<name:',name,'>') as new_name from emp;
select concat('<salary:',salary,'>') as new_salary from emp;

2.查出所有的崗位(去重複)
select distinct post from emp; 

3.查出所有員工名字,以及他們的年薪,年薪的欄位名為annual_year
select concat_ws(':',name,12*salary) as annual_year from emp;

4.where約束

where字句中可以使用:

​ 1.比較運算子:> < >= <= <> !=
​ 2.between 80 and 100 值在80到100之間
​ 3.in(80,90,100)值是80或90或100
​ 4.like'egon%'
​ pattern可以是%或_,
​ %表示任意多字元
​ _表示一個字元
​ 5.邏輯運算子:在多個條件直接可以適用邏輯運算子and or not

#1.單條件查詢
select name from emp where post='sale';

#2.多條件查詢
select name,salary from emp where post='teacher' and salary>10000;

#3.關鍵字between and
select name,salary from emp where salary between 10000 and 20000; 

#4.關鍵字is null(判斷某個欄位是否為null不能用等號,需要用is)
select name,post from emp where post is null;

select name,post from emp where post is not null;

#5.關鍵字in 集合查詢
select name,salary from emp where salary in (3000,3500,4000,9000); 
select concat_ws(':',name,salary) as t1 from emp where salary in (3000,3500,4000,9000);

#6.關鍵字like模糊查詢
萬用字元'%',表示後面的多個字元
select * from emp where name like'eg%';

萬用字元'_',表示後面的一個字元
select * from emp where name like'ego_';

正則:
select * from emp where name regexp'^ale';
確定頭部,通過尾部模糊查詢

select * from emp where name regexp'her$';
確定尾部,通過頭部模糊查詢

select * from emp where name regexp'm{2}';

5.分組查詢:group by

5.1什麼是分組?為什麼分組?

#1.首先明確一點:分組發生在where之後,即分組是基於where之後的到的記錄而進行的

#2.分組指的是:將所有記錄按照某個相同欄位進行歸類,比如針對員工資訊表的職位分組,或者按性別分組

#3.為何要分組呢?
	取每個部門的最高工資(沒有分組取得就是所有部門的最高工資)
	取每個部門的員工數
	取男人數女人數
	
小竅門:'每'這個字後面的欄位就是我們分組的依據

#4.大前提:
	可以按照任意欄位分組,但是分組完畢後,看不到組內資訊,只能檢視到欄位,
	但該欄位相當於介面,我們藉助聚合函式操作此介面即可得到資訊

應用:
select * from emp group by post; #報錯
ERROR 1055 (42000): 'db1.emp.id' isn't in GROUP BY

select post,count(id) from emp group by post; #只能檢視分組依據和使用聚合函式

單獨使用group by 關鍵字分組
select post from emp group by post;
注意:我們按照Post欄位分組,那麼select查詢的欄位只能是post,想要獲取組內的其他相關資訊,需要藉助函式。(如果select * from emp group by post;成立,那麼檢視的是所有組的資訊,那麼分組就沒有他的意義了),簡而言之需要對每個欄位下的資訊進行個性化的操作,就有其意義。
如:
取出每個部門下的最高薪資,那麼有了其分組的意義。
select post, max(salary) from emp group by post;
+-----------+-------------+
| post      | max(salary) |
+-----------+-------------+
| operation |       20000 |
| sale      |        3000 |
| teacher   |     1000000 |
+-----------+-------------+

group by 關鍵字和group_concat()一起使用
檢視每個部門員工的名字
select post,group_concat(name) from emp group by post;
select post,group_concat(name) as emp_member from emp group by post;
由於只能查詢到的欄位是post,當需要顯示欄位name下的資訊時,需要用到group_concat()

group by 與聚合函式一起使用
select post,count(id) as count from emp group by post;
檢視每個組內有多少人(一個id號對應一個人,且不會重複)

強調:
如果我們用unique的欄位作為分組的依據,則每一條記錄自成一組,這種分組沒有意義,
多條記錄之間的某個欄位值相同,該欄位通常用來作為分組的依據

5.2聚合函式

#強調:聚合函式聚合的組的內容,若是沒有分組,則預設一組

select count(*) from emp;
select count(*) from emp where id=1;
select max(salary) from emp;
select min(salary) from emp;
select avg(salary) from emp;
select sum(salary) from emp;
select sum(salary) from emp where id=3; 
#在指定id情況下salary唯一,此聚合函式沒有意義

6.having過濾

having與where的區別:

執行優先順序從高到低:where>group>having

1.where發生在分組group之前,因而where中可以有任意欄位,但是絕對不能使用聚合函式

2.having發生在分組group by之後,因為having中可以使用分組的欄位,無法直接取到其他欄位,可以使用聚合函式
ps:分組group by之後才可以使用聚合函式,如果where中使用聚合函式,代表已經分完組了,那麼將完全違背其執行的優先順序,同理分完組之後having只能使用聚合函式不是其他欄位。

例子:
mysql> select * from emp where salary>99999;
+----+------+------+-----+------------+---------+---------+
| id | name | sex  | age | hire_date  | post    | salary  |
+----+------+------+-----+------------+---------+---------+
|  1 | alex | male |  78 | 2015-03-02 | teacher | 1000000 |
+----+------+------+-----+------------+---------+---------+

mysql> select * from emp having salary>99999;
+----+------+------+-----+------------+---------+---------+
| id | name | sex  | age | hire_date  | post    | salary  |
+----+------+------+-----+------------+---------+---------+
|  1 | alex | male |  78 | 2015-03-02 | teacher | 1000000 |
+----+------+------+-----+------------+---------+---------+
1 row in set (0.00 sec)
#沒有指定分組,默認了group by 的是總表

mysql> select post from emp group by post having salary>99999;
ERROR 1054 (42S22): Unknown column 'salary' in 'having clause'
#指定分組之後

========================================
mysql> select post,max(salary) from emp group by post having salary>99999;
ERROR 1054 (42S22): Unknown column 'salary' in 'having clause'

mysql> select post,max(salary) from emp group by post having max(salary)>99999;
+---------+-------------+
| post    | max(salary) |
+---------+-------------+
| teacher |     1000000 |
+---------+-------------+
顯示每個部門最高薪資大於99999的薪資

練習:

1.查詢男生平均薪資大於3000的職位
select post,avg(salary) from emp where sex='male' group by post having avg(salary)>3000;
+-----------+-------------+
| post      | avg(salary) |
+-----------+-------------+
| operation |  16000.0000 |
| teacher   | 253475.0000 |
+-----------+-------------+

2.查詢各崗位包含的員工個數大於3的崗位名(崗位內包含員工名字、個數)
select post,count(id),group_concat(name) from emp group by post having count(id)>3;
+-----------+-----------+--------------------------------+
| post      | count(id) | group_concat(name)             |
+-----------+-----------+--------------------------------+
| operation |         4 | arther,egon,tank,gg            |
| teacher   |         4 | alex,wupeiqi,yuanhao,liwenzhou |
+-----------+-----------+--------------------------------+

3.查詢各崗位平均薪資大於10000的崗位、平均工資
select post , avg(salary) from emp group by post having avg(salary)>10000;
+-----------+-------------+
| post      | avg(salary) |
+-----------+-------------+
| operation |  16750.0000 |
| teacher   | 253475.0000 |
+-----------+-------------+

4.查詢各崗位平均薪資大於10000且小於10000的崗位名、平均工資
select post , avg(salary) from emp group by post having avg(salary) between 10000 and 20000;
+-----------+-------------+
| post      | avg(salary) |
+-----------+-------------+
| operation |  16750.0000 |
+-----------+-------------+

7.查詢排序:order by

按單列排序
select * from emp order by salary;
select * from emp order by salary asc;
select * from emp order by salary desc; #從大到小

按多列排序
select * from emp order by age,salary desc;
#先按照age排序,如果年紀相同,則按照薪資排序

8.限制查詢的記錄數:limit

示例:
select * from emp order by salary desc limit 3;
+----+-----------+--------+-----+------------+---------+---------+
| id | name      | sex    | age | hire_date  | post    | salary  |
+----+-----------+--------+-----+------------+---------+---------+
|  1 | alex      | male   |  78 | 2015-03-02 | teacher | 1000000 |
|  2 | wupeiqi   | male   |  81 | 2013-03-05 | teacher |    8300 |
|  3 | yuanhao   | male   |  73 | 2014-07-01 | teacher |    3500 |
|  4 | liwenzhou | male   |  28 | 2012-11-01 | teacher |    2100 |
|  5 | yy        | female |  48 | 2015-03-11 | sale    |    3000 |
+----+-----------+--------+-----+------------+---------+---------+
被限制只能看到三條資訊,預設初始位置為0

select * from emp limit 5,5;
從第5條開始,即先查詢出第6條,然後包含這一條在內往後差5條
+----+--------+--------+-----+------------+-----------+--------+
| id | name   | sex    | age | hire_date  | post      | salary |
+----+--------+--------+-----+------------+-----------+--------+
|  6 | dd     | female |  38 | 2010-11-01 | sale      |   2000 |
|  7 | mm     | female |  18 | 2011-03-12 | sale      |   1000 |
|  8 | arther | male   |  28 | 2016-03-11 | operation |  10000 |
|  9 | egon   | male   |  18 | 1997-03-12 | operation |  20000 |
| 10 | tank   | female |  18 | 2013-03-11 | operation |  19000 |
+----+--------+--------+-----+------------+-----------+--------+

六 許可權管理

#授權表
user #該表放行的許可權,針對:所有資料,所有庫下所有表,以及表下的所有欄位
db #該表放行的許可權,針對:某一資料庫,該資料庫下的所有表,以及表下的所有欄位
tables_priv #該表放行的許可權。針對:某一張表,以及該表下的所有欄位
columns_priv #該表放行的許可權,針對:某一個欄位

#按圖解釋:
user:放行db1,db2及其包含的所有
db:放行db1,及其db1包含的所有
tables_priv:放行db1.table1,及其該表包含的所有
columns_prive:放行db1.table1.column1,只放行該欄位