1. 程式人生 > >資料庫之表的使用

資料庫之表的使用

sql_mode 的設定

sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
#設定為安全模式

增語法

1.所有資料按順序插入
insert into 表名 values(值1,....值n)
2.指定欄位匹配插入,可以任意順序
insert into 表名(name,age)values("zb",18)
3.插入查詢結果
insert into 表1(name,age,sex)select 欄位1,欄位2,from 表2

刪語法

1.會記錄自增訊息,操作會被日誌記錄,效率低
delete from 表名[條件]
2.清空表,會重置自增資訊
truncate [table] 表名

改語法

update 表名 set 欄位1 =值1,欄位2 =值2 [條件]
不選擇條件,預設全修改

查語法

select [distinct ] 欄位1 [as 別名] ,欄位2,.....欄位n from [庫名].表名
    where  約束條件
    group by 分組依據
    having 過濾條件
    order by 排序的欄位
    limit 限制顯示的條數
#條件的書寫規則嚴格按照語法順序書寫可以預設,但不可以錯序
#執行順序from >>where>>group by>> having >> distinct>>order by>>limit
#having 只能用於分組後,where只能用於分組前
#分組後的條件均可以使用聚合函式
聚合函式:max(),min(),avg(),sum(),count(),
group_concat():組內欄位拼接,用來檢視組內其他欄位

單表資料

CREATE TABLE emp (
  id int(0) NOT NULL AUTO_INCREMENT,
  name varchar(10) NOT NULL,
  gender enum('男','女','未知') NULL DEFAULT '未知',
  age int(0) NULL DEFAULT 0,
  salary float NULL DEFAULT 0,
  area varchar(20) NULL DEFAULT '中國',
  port varchar(20) DEFAULT '未知',
  dep varchar(20),
  PRIMARY KEY (`id`)
);

INSERT INTO emp VALUES 
    (1, 'yangsir', '男', 42, 10.5, '上海', '浦東', '教職部'),
    (2, 'engo', '男', 38, 9.4, '山東', '濟南', '教學部'),
    (3, 'jerry', '女', 30, 3.0, '江蘇', '張家港', '教學部'),
    (4, 'tank', '女', 28, 2.4, '廣州', '廣東', '教學部'),
    (5, 'jiboy', '男', 28, 2.4, '江蘇', '蘇州', '教學部'),
    (6, 'zero', '男', 28, 8.8, '中國', '黃浦', '諮詢部'),
    (7, 'owen', '男', 28, 8.8, '江蘇', '鹽城', '教學部'),
        (8, 'zero', '女', 18, 4.8, '安徽', '宣城', '教學部'),
    (9, 'ying', '女', 36, 1.2, '安徽', '蕪湖', '諮詢部'),
    (10, 'kevin', '男', 36, 5.8, '山東', '濟南', '教學部'),
    (11, 'monkey', '女', 28, 1.2, '山東', '青島', '教職部'),
    (12, 'san', '男', 30, 9.0, '上海', '浦東', '諮詢部'),
    (13, 'san1', '男', 30, 6.0, '上海', '浦東', '諮詢部'),
    (14, 'san2', '男', 30, 6.0, '上海', '浦西', '教學部');

where 條件

1.比較運算子
select id, name,age from emp where id != 8 ;
2.區間運算
between 10 and 30  
in  (10,20,30) 

select id ,name from emp where id between 10 and 20;
select id ,name from emp where name in ("engo","owen",jerry");
3.邏輯運算子
and or not 
select id ,name ,age from emp where id >10 and age>20;

4.相似運算子
like "_owen%" 模糊匹配, _表示一個字元,%任意字元
select id ,name ,salary from emp  where name like "%g%";

5.正則匹配
語法 欄位 regexp "正則表示式" 注:只支援部分正則語法
查詢姓名有數字的員工資訊
select name from emp  where name regexp ".*[0-9]+.*";

常用函式:
concat (欄位1,....欄位n)完成欄位的拼接
select concat(name,",",age) "資訊" from emp where age > 30;
+------------+
| 資訊 |
+------------+
| yangsir,42 |
| engo,38 |
| ying,36 |
| kevin,36 |
+------------+
concat_ws(x,欄位1,.....,欄位n):完成欄位的拼接,x為連線符
select concat_ws("-",name,age,salary) "高薪人士" from emp where salary > 6;
+-----------------+
| 高薪人士 |
+-----------------+
| yangsir-42-10.5 |
| engo-38-9.4 |
| zero-28-8.8 |
| owen-28-8.8 |
| san-30-9 |

upper()
select concat(upper(name),"-",age) "試試" from emp where salary >6;
lower()
ceil()向上取整
floor()向下取整
round()四捨五入
mysql> select ceil(salary),floor(salary),round(salary) from emp where id=2;
+--------------+---------------+---------------+
| ceil(salary) | floor(salary) | round(salary) |
+--------------+---------------+---------------+
| 10 | 9 | 9 |
+--------------+---------------+---------------+
1 row in set (0.00 sec)

需求:各性別中附屬於教學部的最高薪資
select gender,max(salary) from emp where dep = "教學部" group by gender ;
mysql> select gender,max(salary) from emp where dep = "教學部" group by gender ;
+--------+-------------+
| gender | max(salary) |
+--------+-------------+
| 男 | 9.4 |
| 女 | 3 |
+--------+-------------+

以上性別的其他資訊
select * from emp where salary in (select max(salary) from emp where dep = "教學部" group by gender );
----+-------+--------+------+--------+--------+-----------+-----------+
| id | name | gender | age | salary | area | port | dep |
+----+-------+--------+------+--------+--------+-----------+-----------+
| 2 | engo | 男 | 38 | 9.4 | 山東 | 濟南 | 教學部 |
| 3 | jerry | 女 | 30 | 3 | 江蘇 | 張家港 | 教學部 |
+----+-------+--------+------+--------+--------+-----------+-----------+
子查詢python
將一條查詢結果作為另外一條查詢的條件
語法:一條select語句用()包裹得到的結果作為另一條select語句的條件
單行子查詢:
子查詢語句的結果為一行資料,可以結合 運算子來完成父查詢
多行子查詢:
子查詢語句的結果為多行資料,可以結合 in|all|any
in 是否在結果範圍內,在就取出來
```

子查詢:
select salary from emp where id between 2 and 8;
+--------+
| salary |
+--------+
|    9.4 |
|      3 |
|    2.4 |
|    2.4 |
|    8.8 |
|    8.8 |
最大9.4 ,最小 2.4
all 將結果視為一個整體,此時用 = 號來判斷是沒有資料符合
 select * from emp where salary = all(select max(salary) from emp where dep = "教學部" group by gender );
Empty set (0.00 sec)

用> 號判斷,是需要大於結果中最大的(9.4)
 select * from emp where salary > all(select salary from emp where id between  2 and 8);
+----+---------+--------+------+--------+--------+--------+-----------+
| id | name    | gender | age  | salary | area   | port   | dep       |
+----+---------+--------+------+--------+--------+--------+-----------+
|  1 | yangsir | 男     |   42 |   10.5 | 上海   | 浦東   | 教職部    |
+----+---------+--------+------+--------+--------+--------+-----------+

用< 號判斷,是需要小於結果中最小(2.4)的 
 select * from emp where salary <=  all(select salary from emp where id between  2 and 8);
select * from emp where salary <  all(select salary from emp where id between  2 and 8);
+----+--------+--------+------+--------+--------+--------+-----------+
| id | name   | gender | age  | salary | area   | port   | dep       |
+----+--------+--------+------+--------+--------+--------+-----------+
|  9 | ying   | 女     |   36 |    1.2 | 安徽   | 蕪湖   | 諮詢部    |
| 11 | monkey | 女     |   28 |    1.2 | 山東   | 青島   | 教職部    |
+----+--------+--------+------+--------+--------+--------+-----------+
any:
= 子查詢結果中的任意一個都可以
 select * from emp where salary = any(select salary from emp where id between  2 and 8);
+----+-------+--------+------+--------+--------+-----------+-----------+
| id | name  | gender | age  | salary | area   | port      | dep       |
+----+-------+--------+------+--------+--------+-----------+-----------+
|  2 | engo  | 男     |   38 |    9.4 | 山東   | 濟南      | 教學部    |
|  3 | jerry | 女     |   30 |      3 | 江蘇   | 張家港    | 教學部    |
|  4 | tank  | 女     |   28 |    2.4 | 廣州   | 廣東      | 教學部    |
|  5 | jiboy | 男     |   28 |    2.4 | 江蘇   | 蘇州      | 教學部    |
|  6 | zero  | 男     |   28 |    8.8 | 中國   | 黃浦      | 諮詢部    |
|  7 | owen  | 男     |   28 |    8.8 | 安徽   | 宣城      | 教學部    |
+----+-------+--------+------+--------+--------+-----------+-----------+

< 小於任意一個都可以也就是小於最大的都可以
 select * from emp where salary < any(select salary from emp where id between  2 and 8);
+----+--------+--------+------+--------+--------+-----------+-----------+
| id | name   | gender | age  | salary | area   | port      | dep       |
+----+--------+--------+------+--------+--------+-----------+-----------+
|  3 | jerry  | 女     |   30 |      3 | 江蘇   | 張家港    | 教學部    |
|  4 | tank   | 女     |   28 |    2.4 | 廣州   | 廣東      | 教學部    |
|  5 | jiboy  | 男     |   28 |    2.4 | 江蘇   | 蘇州      | 教學部    |
|  6 | zero   | 男     |   28 |    8.8 | 中國   | 黃浦      | 諮詢部    |
|  7 | owen   | 男     |   28 |    8.8 | 安徽   | 宣城      | 教學部    |
|  9 | ying   | 女     |   36 |    1.2 | 安徽   | 蕪湖      | 諮詢部    |
| 10 | kevin  | 男     |   36 |    5.8 | 山東   | 濟南      | 教學部    |
| 11 | monkey | 女     |   28 |    1.2 | 山東   | 青島      | 教職部    |
| 12 | san    | 男     |   30 |      9 | 上海   | 浦東      | 諮詢部    |
| 13 | san1   | 男     |   30 |      6 | 上海   | 浦東      | 諮詢部    |
| 14 | san2   | 男     |   30 |      6 | 上海   | 浦西      | 教學部    |
+----+--------+--------+------+--------+--------+-----------+-----------+
>大於任意一個都可以,也就是大於最小的就可以
 select * from emp where salary > any(select salary from emp where id between  2 and 8);
+----+---------+--------+------+--------+--------+-----------+-----------+
| id | name    | gender | age  | salary | area   | port      | dep       |
+----+---------+--------+------+--------+--------+-----------+-----------+
|  1 | yangsir | 男     |   42 |   10.5 | 上海   | 浦東      | 教職部    |
|  2 | engo    | 男     |   38 |    9.4 | 山東   | 濟南      | 教學部    |
|  3 | jerry   | 女     |   30 |      3 | 江蘇   | 張家港    | 教學部    |
|  6 | zero    | 男     |   28 |    8.8 | 中國   | 黃浦      | 諮詢部    |
|  7 | owen    | 男     |   28 |    8.8 | 安徽   | 宣城      | 教學部    |
| 10 | kevin   | 男     |   36 |    5.8 | 山東   | 濟南      | 教學部    |
| 12 | san     | 男     |   30 |      9 | 上海   | 浦東      | 諮詢部    |
| 13 | san1    | 男     |   30 |      6 | 上海   | 浦東      | 諮詢部    |
| 14 | san2    | 男     |   30 |      6 | 上海   | 浦西      | 教學部    |
+----+---------+--------+------+--------+--------+-----------+-----------+

having篩選

完成分組之後的篩選
注意:having 條件是實現聚合結果層面上的篩選>=拿聚合結果來判斷

平均薪資大於6萬的部門
select dep,avg(salary) from emp group by dep  having avg(salary) > 6;
+-----------+-------------------+
| dep       | avg(salary)       |
+-----------+-------------------+
| 諮詢部    | 6.250000059604645 |
+-----------+-------------------+

order by 排序

完成排序
注意:可以使用聚合函式,哪怕沒有明確group by
沒有明確分組,就是以整張表作為大組
升序|降序 : asc | desc
#不指定順序,預設為升序
select  * from emp order by salary;
+----+---------+--------+------+--------+--------+-----------+-----------+
| id | name    | gender | age  | salary | area   | port      | dep       |
+----+---------+--------+------+--------+--------+-----------+-----------+
| 11 | monkey  | 女     |   28 |    1.2 | 山東   | 青島      | 教職部    |
|  9 | ying    | 女     |   36 |    1.2 | 安徽   | 蕪湖      | 諮詢部    |
|  4 | tank    | 女     |   28 |    2.4 | 廣州   | 廣東      | 教學部    |
|  5 | jiboy   | 男     |   28 |    2.4 | 江蘇   | 蘇州      | 教學部    |
|  3 | jerry   | 女     |   30 |      3 | 江蘇   | 張家港    | 教學部    |
| 10 | kevin   | 男     |   36 |    5.8 | 山東   | 濟南      | 教學部    |
| 14 | san2    | 男     |   30 |      6 | 上海   | 浦西      | 教學部    |
| 13 | san1    | 男     |   30 |      6 | 上海   | 浦東      | 諮詢部    |
|  7 | owen    | 男     |   28 |    8.8 | 安徽   | 宣城      | 教學部    |
|  6 | zero    | 男     |   28 |    8.8 | 中國   | 黃浦      | 諮詢部    |
| 12 | san     | 男     |   30 |      9 | 上海   | 浦東      | 諮詢部    |
|  2 | engo    | 男     |   38 |    9.4 | 山東   | 濟南      | 教學部    |
|  1 | yangsir | 男     |   42 |   10.5 | 上海   | 浦東      | 教職部    |
+----+---------+--------+------+--------+--------+-----------+-----------+

eg: order by age desc => 按照年齡降序
 select * from emp order by age desc;
+----+---------+--------+------+--------+--------+-----------+-----------+
| id | name    | gender | age  | salary | area   | port      | dep       |
+----+---------+--------+------+--------+--------+-----------+-----------+
|  1 | yangsir | 男     |   42 |   10.5 | 上海   | 浦東      | 教職部    |
|  2 | engo    | 男     |   38 |    9.4 | 山東   | 濟南      | 教學部    |
| 10 | kevin   | 男     |   36 |    5.8 | 山東   | 濟南      | 教學部    |
|  9 | ying    | 女     |   36 |    1.2 | 安徽   | 蕪湖      | 諮詢部    |
| 13 | san1    | 男     |   30 |      6 | 上海   | 浦東      | 諮詢部    |
| 12 | san     | 男     |   30 |      9 | 上海   | 浦東      | 諮詢部    |
| 14 | san2    | 男     |   30 |      6 | 上海   | 浦西      | 教學部    |
|  3 | jerry   | 女     |   30 |      3 | 江蘇   | 張家港    | 教學部    |
|  6 | zero    | 男     |   28 |    8.8 | 中國   | 黃浦      | 諮詢部    |
|  5 | jiboy   | 男     |   28 |    2.4 | 江蘇   | 蘇州      | 教學部    |
| 11 | monkey  | 女     |   28 |    1.2 | 山東   | 青島      | 教職部    |
|  4 | tank    | 女     |   28 |    2.4 | 廣州   | 廣東      | 教學部    |
|  7 | owen    | 男     |   28 |    8.8 | 安徽   | 宣城      | 教學部    |
+----+---------+--------+------+--------+--------+-----------+-----------+

需求:將部門按照部門平均工資降序方式排序
select dep,avg(salary) from emp group by dep order by avg(salary) desc;
+-----------+-------------------+
| dep       | avg(salary)       |
+-----------+-------------------+
| 諮詢部    | 6.250000059604645 |
| 教職部    | 5.850000023841858 |
| 教學部    | 5.400000027247837 |
+-----------+-------------------+

limit 限制

限制最終結果的資料行數
注意:limit 只與數字結合使用
使用方法:
limit 1:只顯示一行資料
limit 6, 5: 從第6+1行開始顯示5條資料(索引從0開始)

需求:
獲得薪資最高的人的一條資訊
select * from emp order by salary desc limit 1;
+----+---------+--------+------+--------+--------+--------+-----------+
| id | name    | gender | age  | salary | area   | port   | dep       |
+----+---------+--------+------+--------+--------+--------+-----------+
|  1 | yangsir | 男     |   42 |   10.5 | 上海   | 浦東   | 教職部    |
+----+---------+--------+------+--------+--------+--------+-----------+

1 查出所有員工的名字,薪資,格式為
<名字:egon> <薪資:3000>
select concat("<名字:",name,">") "name" , concat("<薪資:",salary,">") "salary" from emp limit 2;
+------------------+---------------+
| name | salary |
+------------------+---------------+
| <名字:yangsir> | <薪資:10.5> |
| <名字:engo> | <薪資:9.4> |
+------------------+---------------+
2 查出所有的崗位(去掉重複)
select distinct dep from emp;
+-----------+
| dep |
+-----------+
| 教職部 |
| 教學部 |
| 諮詢部 |
+-----------+
3 查出所有員工名字,以及他們的年薪,年薪的欄位名為annual_year
select name,salary*12 "annual_year" from emp;
+---------+--------------------+
| name | annual_year |
+---------+--------------------+
| yangsir | 126 |
| engo | 112.79999542236328 |
| jerry | 36 |
| tank | 28.80000114440918 |
| jiboy | 28.80000114440918 |
| zero | 105.60000228881836 |
| owen | 105.60000228881836 |
| ying | 14.40000057220459 |
| kevin | 69.60000228881836 |
| monkey | 14.40000057220459 |
| san | 108 |
| san1 | 72 |
| san2 | 72 |
+---------+--------------------+

  1. 檢視崗位是教學部的員工姓名、年齡
    select name,age from emp where dep ="教學部";
  2. 檢視崗位是教學部且年齡大於30歲的員工姓名、年齡
    select name,age,dep from emp where dep ="教學部" and age>30;
  3. 檢視崗位是教學部且薪資在2-6範圍內的員工姓名、年齡、薪資
    select name,age,salary from emp where salary between 2 and 6;
  4. 檢視崗位描述不為NULL的員工資訊
    select * from emp where dep != null;
  5. 檢視崗位是teacher且薪資是10000或9000或30000的員工姓名、年齡、薪資
    select name,age,salary from emp where salary in (10000,9000,30000);
  6. 檢視崗位是teacher且薪資不是10000或9000或30000的員工姓名、年齡、薪資
    select name,age,salary from emp where dep = "teacher" and salary not in(10000,9000,30000);

  7. 檢視崗位是teacher且名字是jin開頭的員工姓名、年薪
    select name,salary from emp where dep = "teacher" and regexp "^jin.*"

  8. 查詢崗位名以及崗位包含的所有員工名字
    select dep,group_concat(name) from emp group by dep;
  9. 查詢崗位名以及各崗位內包含的員工個數
    select dep,count(name) from emp group by dep;
  10. 查詢公司內男員工和女員工的個數
    select gender,count(gender) from emp group by gender;
  11. 查詢崗位名以及各崗位的平均薪資
    select dep,avg(salary) "平均薪資" from emp group by dep;
  12. 查詢崗位名以及各崗位的最高薪資
    select dep,max(salary) "最高薪資" from emp group by dep;

  13. 查詢崗位名以及各崗位的最低薪資
    select dep,min(salary) "最低薪資" from emp group by dep;
  14. 查詢男員工與男員工的平均薪資,女員工與女員工的平均薪資
    select gender "性別",avg(salary) "平均薪資" from emp group by gender;

  15. 查詢各崗位內包含的員工個數大於2的崗位名、崗位內包含員工名字、個數
    select dep,group_concat(name)"name",count(id)"count" from emp group by dep having count(id) > 2;
    +-----------+---------------------------------------+-------+
    | dep | name | count |
    +-----------+---------------------------------------+-------+
    | 諮詢部 | san1,san,ying,zero | 4 |
    | 教學部 | san2,kevin,owen,jiboy,tank,jerry,engo | 7 |
    +-----------+---------------------------------------+-------+
  16. 查詢各崗位平均薪資大於 4 的崗位名、平均工資
    select dep,avg(salary) from emp group by dep having avg(salary) > 4;
  17. 查詢各崗位平均薪資大於4且小於8的崗位名、平均工資
    select dep,avg(salary) from emp group by dep having avg(salary) >4 and avg(salary)<8;

  18. 查詢所有員工資訊,先按照age升序排序,如果age相同則按照薪資降序排序
    select * from emp order by age, salary desc;

  19. 查詢各崗位平均薪資大於4的崗位名、平均工資,結果按平均薪資升序排列
    select dep ,avg(salary) from emp group by dep order by avg(salary);

  20. 查詢各崗位平均薪資大於14的崗位名、平均工資,結果按平均薪資降序排列
    select dep ,avg(salary) from emp group by dep order by avg(salary) desc;