數據庫的查詢命令


條件

from / where / group by / having distinct / order by / limit

  • 使用這些條件可以按照需求任意選擇,但是順序必須按照上面的順序來
  • 特殊點:distinct是放在最前面的,但是執行邏輯是上面的順序

去重:distinct

- select  distinct  *  from  表;
- 對於你查詢出的所有記錄,所有字段必須完全一模一樣才會去重
	- 可以改為  任意字段

常用函數

- concat()/concat_ws()
  - 拼接
  - concat(字段,['拼接符號'],字段)
    - 將字段按照你寫的格式拼接
  - concat_ws('拼接符號',字段n)
    - 所有字段按照第一拼接符號拼接
- upper()/lower()
  - upper()將字符串都變成大寫
  - lower()將字符串都變成小寫
- ceil()/floor()/round()
  - ceil(浮點型字段)
    - 向上取整
  - floor(浮點型字段)
    - 向下取整
  - round(浮點型字段)
    - 小於0.5的舍去
    - 大於0.5的進一位
- 整型可以使用運算符直接運算

案例

"""
拼接:concat() | concat_ws()
大小寫:upper() | lower()
浮點型操作:ceil() | floor() | round()
整型:可以直接運算
"""
mysql>: select name,area,port from emp;
mysql>: select name as 姓名, concat(area,'-',port) 地址 from emp;  # 上海-浦東
mysql>: select name as 姓名, concat_ws('-',area,port,dep) 信息 from emp;  # 上海-浦東-教職部

mysql>: select upper(name) 姓名大寫,lower(name) 姓名小寫 from emp;

mysql>: select id,salary,ceil(salary)上薪資,floor(salary)下薪資,round(salary)入薪資 from emp;

mysql>: select name 姓名, age 舊年齡, age+1 新年齡 from emp;

條件:where

- where  判斷規則;

  - 篩選出符合規則的記錄

- 判斷規則

  - 比較符合

    - > < >=  <=  =  !=

  - 區間符合

    - between  開始  and 結束
      - 在滿足開始和結束中間都符合
    - in   (自定義容器)
      - 只要在里面的都符合

  - 邏輯符合

    - and  or   not

  - 相似符合

    - like   _或者%
    - _表示代替一個任意字符
    - %表示代替任意個任意字符

  - 正則符合

    - regexp   正則語法
    - 支持部分正則語法

案例

# 多條件協調操作導入:where 奇數 [group by 部門 having 平均薪資] order by [平均]薪資 limit 1

mysql>: select * from emp where id<5 limit 1;  # 正常
mysql>: select * from emp limit 1 where id<5;  # 異常,條件亂序

# 判斷規則
"""
比較符合:>  |  <  |  >=  |  <=  |  =  |  !=
區間符合:between 開始 and 結束 |  in(自定義容器)
邏輯符合:and  |  or  |  not
相似符合:like _|%
正則符合:regexp 正則語法
"""
mysql>: select * from emp where salary>5;
mysql>: select * from emp where id%2=0;

mysql>: select * from emp where salary between 6 and 9;

mysql>: select * from emp where id in(1, 3, 7, 20);

# _o 某o | __o 某某o | _o% 某o* (*是0~n個任意字符) | %o% *o*
mysql>: select * from emp where name like '%o%';
mysql>: select * from emp where name like '_o%';  
mysql>: select * from emp where name like '___o%';

# sql只支持部分正則語法
mysql>: select * from emp where name regexp '.*\d';  # 不支持\d代表數字,認為\d就是普通字符串
mysql>: select * from emp where name regexp '.*[0-9]';  # 支持[]語法

分組與篩選:group by | having

  • where與having

    • 首先要知道having也是用來篩選的
    • 在不分組的情況下,使用where 和 having是一樣的
    • 並且,where和having的使用方式完全一致
    • PS:having可以對聚合結果進行篩選,還可以對分組的數據進行篩選
    • PS:where可以分組前使用
    # 表象:在沒有分組的情況下,where與having結果相同
    # 重點:having可以對 聚合結果 進行篩選
    mysql>: select * from emp where salary > 5;
    mysql>: select * from emp having salary > 5;
    
    mysql>: select * from emp where id in (5, 10, 15, 20);
    mysql>: select * from emp having id in (5, 10, 15, 20);
    
  • 聚合函數

    • 將多條數據統一處理的方式叫做聚合
    • max():求最大值
    • min():求最大值
    • avg():求平均數
    • sum();求和
    • count():求個數
    • group_concat():組內字段拼接,用來查看組內其他字段
      • 無法設置拼接方式默認以,連接
    """
    max():最大值
    min():最小值
    avg():平均值
    sum():和
    count():記數
    group_concat():組內字段拼接,用來查看組內其他字段
    """
    
  • 分組查詢 group by

    # 修改my.ini配置重啟mysql服務
    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
    
    # 在sql_mode沒有 ONLY_FULL_GROUP_BY 限制下,可以執行,但結果沒有意義
    # 有 ONLY_FULL_GROUP_BY 限制,報錯
    mysql>: select * from emp group by dep;
    
    # 分組后,表中數據考慮范圍就不是 單條記錄,因為每個分組都包含了多條記錄,參照分組字段,對每個分組中的 多條記錄 統一處理
    # eg: 按部門分組,每個部門都有哪些人、最高的薪資、最低的薪資、平均薪資、組里一共有多少人
    
    # 將多條數據統一處理,這種方式就叫 聚合
    # 每個部門都有哪些人、最高的薪資、最低的薪資、平均薪資 都稱之為 聚合結果 - 聚合函數操作的結果
    # 注:參與分組的字段,也歸於 聚合結果
    
    mysql>: 
    select 
    	dep 部門,
    	group_concat(name) 成員,
    	max(salary) 最高薪資,
    	min(salary) 最低薪資,
    	avg(salary) 平均薪資,
    	sum(salary) 總薪資,
    	count(gender) 人數
    from emp group by dep;
    
    mysql>: select 
    	dep 部門,
    	max(age) 最高年齡
    from emp group by dep;
    
    # 總結:分組后,查詢條件只能為 分組字段 和 聚合函數操作的聚合結果
    
    - 修改my.ini配置重啟mysql服務
    
    	- 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
    
    - 在sql_mode沒有 ONLY_FULL_GROUP_BY 限制下,可以執行,但結果沒有意義
    - 有 ONLY_FULL_GROUP_BY 限制,報錯
    - 分組后的查詢就不是單條記錄了,而是一組一組的記錄,對每組記錄做同一處理
    - 用聚合函數來處理這些數據
    
  • 分組后的having

    ​ having可以對 聚合結果 再進行篩選,where不可以

    mysql>: 
    select 
    	dep 部門,
    	group_concat(name) 成員,
    	max(salary) 最高薪資,
    	min(salary) 最低薪資,
    	avg(salary) 平均薪資,
    	sum(salary) 總薪資,
    	count(gender) 人數
    from emp group by dep;
    
    # 最低薪資小於2
    mysql>:
    select 
    	dep 部門,
    	group_concat(name) 成員,
    	max(salary) 最高薪資,
    	min(salary) 最低薪資,
    	avg(salary) 平均薪資,
    	sum(salary) 總薪資,
    	count(gender) 人數
    from emp group by dep having min(salary)<2;
    
    # having可以對 聚合結果 再進行篩選,where不可以
    
  • 聯合分組

    • group by 字段1,...,字段n
    • 將所有字段的結果看作一個整體,進而來進行分組

排序

  • 排序規則

    # order by 主排序字段 [asc|desc], 次排序字段1 [asc|desc], ...次排序字段n [asc|desc]
    
    • order by 主排序字段 [asc/desc][,次排序字段 [asc/desc]...]
      • asc 升序排序,可以不寫,默認升序
      • desc 降序排序
  • 未分組狀態下

    mysql>: select * from emp;
    
    # 按年齡升序
    mysql>: select * from emp order by age asc;
    # 按薪資降序
    mysql>: select * from emp order by salary desc;
    
    # 按薪資降序,如果相同,再按年齡降序
    mysql>: select * from emp order by salary desc, age desc;
    # 按齡降序,如果相同,再按薪資降序
    mysql>: select * from emp order by age desc, salary desc;
    
  • 分組狀態下

    mysql>:
    select 
    	dep 部門,
    	group_concat(name) 成員,
    	max(salary) 最高薪資,
    	min(salary) 最低薪資,
    	avg(salary) 平均薪資,
    	sum(salary) 總薪資,
    	count(gender) 人數
    from emp group by dep;
    
    # 最高薪資降序
    mysql:
    select 
    	dep 部門,
    	group_concat(name) 成員,
    	max(salary) 最高薪資,
    	min(salary) 最低薪資,
    	avg(salary) 平均薪資,
    	sum(salary) 總薪資,
    	count(gender) 人數
    from emp group by dep
    order by 最高薪資 desc;
    
  • 限制 limit

    limit 條數/偏移量,條數

# 語法:limit 條數  |  limit 偏移量,條數
mysql>: select name, salary from emp where salary<8 order by salary desc limit 1;

mysql>: select * from emp limit 5,3;  # 先偏移5條滿足條件的記錄,再查詢3條

單表查詢

"""
增:
insert [into] 
	[數據庫名.]表名[(字段1[, ..., 字段n])] 
values 
	(數據1[, ..., 數據n])[, ..., (數據1[, ..., 數據n])];

刪:
delete from [數據庫名.]表名 [條件];

改:
updata [數據庫名.]表名 set 字段1=值1[, ..., 字段n=值n] [條件];

查:
select [distinct] 字段1 [[as] 別名1],...,字段n [[as] 別名n] from [數據庫名.]表名 [條件];
"""

# 條件:from、where、group by、having、distinct、order by、limit => 層層篩選后的結果
# 注:一條查詢語句,可以擁有多種篩選條件,條件的順序必須按照上方順序進行逐步篩選,distinct稍有特殊(書寫位置),條件的種類可以不全
# 可以缺失,但不能亂序


  • insert [into]
    [數據庫名].表名[字段n]
    vlaues
    (數據n);
    • 數據與字段要一一對應
    • 如果字段沒有寫表示所有的數據都要填寫

  • delete from 數據庫名].表名 [條件];

  • updata [數據庫名.]表名 set 字段1=值1[, ..., 字段n=值n] [條件];

  • updata [數據庫名.]表名 set 字段1=值1[, ..., 字段n=值n] [條件];

連表查詢

連接

# 連接:將有聯系的多張表通過關聯(有聯系就行,不一定是外鍵)字段,進行連接,形參一張大表
# 連表查詢:在大表的基礎上進行查詢,就稱之為連表查詢

# 將表與表建立連接的方式有四種:內連接、左連接、右連接、全連接
  • 建立表與表間的聯系,可以是兩張及以上
  • 不要求外鍵,有聯系就行
  • 連接后是一大張包所有表字段的大表—實際上是多張表
  • 連表查詢
    • 在張大表的基礎上進行查詢叫做連表查詢
  • 建立表與表連接的方式有四種
    • 內連接
    • 左連接
    • 右連接
    • 全連接

笛卡爾積

# 笛卡爾積: 集合 X{a, b} * Y{o, p, q} => Z{{a, o}, {a, p}, {a, q}, {b, o}, {b, p}, {b, q}}

mysql>: select * from emp, dep;

# 總結:是兩張表 記錄的所有排列組合,數據沒有利用價值
  • select * from 表1 , 表2;
  • 將兩張表的記錄進行全排列

一對多

  • 內連接

    # 關鍵字:inner join on
    # 語法:from A表 inner join B表 on A表.關聯字段=B表.關聯字段
    
    mysql>: 
    select 
    	emp.id,emp.name,salary,dep.name,work 
    from emp inner join dep on emp.dep_id = dep.id 
    order by emp.id;
    
    # 總結:只保留兩個表有關聯的數據
    
    • from A表 [inner] join B表 on A表.關聯字段=B表關聯字段
  • 左連接

    # 關鍵字:left join on
    # 語法:from 左表 left join 右表 on 左表.關聯字段=右表.關聯字段
    
    mysql>: 
    select 
    	emp.id,emp.name,salary,dep.name,work 
    from emp left join dep on emp.dep_id = dep.id 
    order by emp.id;
    
    # 總結:保留左表的全部數據,右表有對應數據直接連表顯示,沒有對應關系空填充
    
    • from A表 left join B表 on A表.關聯字段=B表關聯字段
  • 右連接

    # 關鍵字:right join on
    # 語法:from A表 right join B表 on A表.關聯字段=B表關聯字段
    
    mysql>: 
    select 
    	emp.id,emp.name,salary,dep.name,work 
    from emp right join dep on emp.dep_id = dep.id 
    order by emp.id;
    
    # 總結:保留右表的全部數據,左表有對應數據直接連表顯示,沒有對應關系空填充
    
    • from A表 right join B表 on A表.關聯字段=B表關聯字段
  • 左右可以相互轉化

    mysql>: 
    select 
    	emp.id,emp.name,salary,dep.name,work 
    from emp right join dep on emp.dep_id = dep.id 
    order by emp.id;
    
    mysql>: 
    select 
    	emp.id,emp.name,salary,dep.name,work 
    from dep left join emp on emp.dep_id = dep.id 
    order by emp.id;
    
    # 總結:更換一下左右表的位置,相對應更換左右連接關鍵字,結果相同
    
    • 交AB表位置和left/right關鍵字
    • 形成的新連接是一模一樣的
  • 全連接

    mysql>: 
    select 
    	emp.id,emp.name,salary,dep.name,work 
    from emp left join dep on emp.dep_id = dep.id 
    
    union
    
    select 
    	emp.id,emp.name,salary,dep.name,work 
    from emp right join dep on emp.dep_id = dep.id 
    
    order by id;
    
    # 總結:左表右表數據都被保留,彼此有對應關系正常顯示,彼此沒有對應關系均空填充對方
    
    • select 表的字段名
      from A表 left join B表 on A表.關聯字段=B表關聯字段
      union
      select 表的字們
      from A表 right join B表 on A表.關聯字段=B表關聯字段
      • 因為mysql了不支持全連接,所以兩張表的左右連接和union實現全連接
      • 注意:兩個左右連接必都先select形成一張新表,再用union連接成一張信新表
      • 之后的操作只能對新表來完成
      • PS:兩個select中的字段們必須完全一致,連順序也要一樣

一對一與一對多情況一致

# 創建一對一 作者與作者詳情 表
create table author(
	id int,
    name varchar(64),
    detail_id int
);
create table author_detail(
	id int,
    phone varchar(11)
);
# 填充數據
insert into author values(1, 'Bob', 1), (2, 'Tom', 2), (3, 'ruakei', 0);
insert into author_detail values(1, '13344556677'), (2, '14466779988'), (3, '12344332255');

# 內連
select author.id,name,phone from author join author_detail on author.detail_id = author_detail.id order by author.id;

# 全連
select author.id,name,phone from author left join author_detail on author.detail_id = author_detail.id
union
select author.id,name,phone from author right join author_detail on author.detail_id = author_detail.id
order by id;

多對多:兩表兩表建立連接

# 在一對一基礎上,建立 作者與書 的多對多關系關系

# 利用之前的作者表
create table author(
	id int,
    name varchar(64),
    detail_id int
);
insert into author values(1, 'Bob', 1), (2, 'Tom', 2), (3, 'ruakei', 0);

# 創建新的書表
create table book(
	id int,
    name varchar(64),
    price decimal(5,2)
);
insert into book values(1, 'python', 3.66), (2, 'Linux', 2.66), (3, 'Go', 4.66);

# 創建 作者與書 的關系表
create table author_book(
	id int,
    author_id int,
    book_id int
);
# 數據:author-book:1-1,2  2-2,3  3-1,3
insert into author_book values(1,1,1),(2,1,2),(3,2,2),(4,2,3),(5,3,1),(6,3,3);

# 將有關聯的表一一建立連接,查詢所以自己所需字段
select book.name, book.price, author.name, author_detail.phone from book 
join author_book on book.id = author_book.book_id
join author on author_book.author_id = author.id
left join author_detail on author.detail_id = author_detail.id;
  • 前提兩張被關系表個關系表都創建完成了【表里有數據了】
  • 將有關聯的表一一建立連接,查詢所以自己所需字段
  • select 表的字段 from A表
    join 關系表 on A表.關聯字段=關系表.關聯字段
    join B表 on 關系表.關聯字段=B表.關聯呢字段;
  • join可以寫多個,但內鏈連接會導致數據的丟失

子查詢——增刪改都是對表的數據進行修改,所以子查詢不要和被修改的表同表

  • insert into 表 select 子查詢

  • delete from 表 條件是子查詢

  • update 表 set 字段=值 條件是子查詢

  • select 字段 from 表 條件是子查詢


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM