MySQL基礎(七):DQL語句

  • 本博客是《MySQL基礎》系列博客的第七部分,主要介紹MySQL語句中的DQL語句,即我們常說的查詢語句的基本用法,包括簡單的單表查詢、去重、排序、分組查詢、統計查詢、多表查詢、連接查詢、子查詢和聯合查詢
  • 本博客既爲方便自己查看複習而作,亦爲你而作,望能有所裨益
  • 學習交流請聯繫 [email protected]

DQL簡介

DQL,即Data Definition Language,數據查詢語言,用於數據庫、數據表等數據的查詢,也就是我們常說的增刪改查中的

DQL用法

示例數據庫

爲了後續介紹方便,我們使用MySQL自帶的數據庫 Sakila
在這裏插入圖片描述
此外,在使用數據庫前,我們需要對數據庫有一個基本的瞭解,如果一個一個表打開看顯然不太合適,這時候就需要有一個全局視圖來幫助我們。而MySQL確實也提供了這樣的功能:
在這裏插入圖片描述

  1. 首次打開時需要自行找到示例數據庫所在地,默認存放在MySQL文件夾下的Samples and Examples文件夾內,以.mwb爲後綴名
    在這裏插入圖片描述
    在這裏插入圖片描述
  2. 打開後是這樣的畫面:
    在這裏插入圖片描述
    在這裏插入圖片描述
  3. 進而瞭解到該數據庫處理的是租賃事務,其中有顧客數據,有商家數據以及租賃商品的數據。

下面我們就開始學習SQL語句的重頭戲——查詢語句SELECT的用法吧。

簡單的單表查詢

/* 簡單的表查詢*/

select * from <數據庫>.<數據表>; -- 查詢某一數據庫中某表的全部信息

select <字段名> from <數據庫>.<數據表>; -- 查詢某表的某些字段
select actor_id,first_name from actor; 
-- 查詢actor表中actor_id和first_name兩個字段

select <字段名> from <數據庫>.<數據表> where <條件>; -- 條件查詢
select actor_id,first_name from actor where actor_id > 10; 
-- 查詢actor表中actor_id和first_name兩個字段中actor_id大於10的字段
select actor_id,first_name from actor where actor_id != 10;
-- 查詢actor表中actor_id和first_name兩個字段中actor_id不等於10的字段
select actor_id,first_name from actor where actor_id between 10 and 20;
-- -- 查詢actor表中actor_id和first_name兩個字段中actor_id位於[10,20]區間內的字段
select actor_id,first_name from	actor where actor_id in (10,13,29);
-- 查詢actor表中actor_id和first_name兩個字段中actor_id爲10,13和29的字段
select actor_id,first_name from actor where actor_id not in (10,13,29);
-- 查詢actor表中actor_id和first_name兩個字段中actor_id不爲10,13和29的字段

-- 通配符的使用 
select actor_id,first_name from actor where first_name like 'j%'; 
/* 查詢actor表中actor_id和first_name兩個字段中first_name
爲以j開頭,後跟任意個字符的字段 */
select actor_id,first_name from actor where first_name like 'j__'; 
/* 查詢actor表中actor_id和first_name兩個字段中first_name
爲以j開頭長度爲3個字符的字段,一個_代表一個字符 */
select actor_id,first_name from actor where first_name  not like 'j%'; 
/* 查詢actor表中actor_id和first_name兩個字段中first_name
不以j開頭,後跟任意個字符的字段 */
select actor_id,first_name from actor where first_name like 'j%' and last_name like '%s';
/* 查詢actor表中actor_id和first_name兩個字段中first_name
爲以j開頭且last_name爲以s結尾的字段 */
select actor_id,first_name from actor where first_name like 'j%' or last_name like '%s';
/* 查詢actor表中actor_id和first_name兩個字段中first_name
爲以j開頭或last_name爲以s結尾的字段 */

去重


-- 去重(distinct)
-- 原始數據中不可避免地存在重複數據,因此在分析數據前要對數據進行去重
select distinct <字段名> from <數據庫>.<數據表>;

select first_name from actor; -- 返回200個名字
select distinct first_name from actor; -- 去重後返回128個名字
select first_name,last_name from actor; -- 返回200個姓名 
select distinct first_name,last_name from actor; -- 去重後返回199個姓名

排序

-- 排序
-- 數據庫中記錄的默認排序爲升序
select <字段名> from <數據庫>.<數據表> order by <字段名> [desc];
-- desc爲降序,添加則將該關鍵詞前面的字段降序排列後返回查詢結果

select actor_id,first_name from actor order by actor_id desc; 
-- 按actor_id降序排列後返回查詢結果 
select actor_id,first_name from actor order by actor_id desc, first_name; 
-- 先按演員號降序排列,再按演員名升序排列(字段爲字符串時排序效果不明顯)
select actor_id,first_name from actor order by actor_id desc, first_name desc; 
-- 先按演員號降序排列,再按演員名降序排列  

分組查詢

-- 分組查詢
-- 數據量較大時,通常對數據進行分組,以瞭解數據的大致情況
select <字段名> from <數據庫>.<數據表> group by <分組字段名>;

select * from film group by rating;
-- 將rating分組後再查看所有數據 
select rating,group_concat(film_id) from film group by rating; 
-- 查看每個等級對應的記錄編號,concat表示合併多個數組或字符串  
select rating,count(film_id) from film group by rating; 
-- 查看每個等級對應的記錄數
select rating,count(film_id) from film group by rating  with rollup; 
-- 查看每個等級對應的記錄數併合計

-- 在分組查詢的基礎上進行條件查詢
select <字段名> from <數據庫>.<數據表> group by <分組字段名> having <條件>;
select rating,count(film_id) from film group by rating having count(film_id) > 200; -- 查詢電影數目大於200的某一等級及該等級的電影數

-- 在分組查詢的基礎上進行排序查詢
select rating,count(film_id),rental_duration from film group by rating,rental_duration order by rating; 
-- 在rating分組的基礎上用rental_duration分組,再以rating字段升序排列 

統計查詢

-- 統計查詢
-- 爲了對錶中數據有個初步瞭解,通常情況下我們要進行下簡單的統計查詢
-- 常用的統計函數有count、sum、avg、max、min等
select <統計函數>(字段名) from <數據庫>.<數據表>;

select * from sakila.payment; -- 以payment表爲例

select count(payment_id) from actor; 
-- 有多少條顧客的購買記錄  
select customer_id,sum(amount) from payment where customer_id = 1; 
-- 編號爲1的顧客的付款總額
select customer_id,sum(amount) from payment group by customer_id; 
-- 每個顧客的付款總額 
select customer_id,avg(amount) from payment group by customer_id; 
-- 每個顧客的平均付款額 
select customer_id,max(amount),min(amount) from payment group by customer_id; 
-- 每個顧客單次付款的最大值和最小值  

連接查詢

有時候我們需要查詢的數據分散在不同的表中,此時我們就需要將這些存放在不同的表中的數據連接起來,也稱多表查詢

示例數據表

由於Sakila數據庫中的表的數據過多,因此,爲了演示方便,我們創建兩張新的數據表用來演示學習:
(順便複習一下DDL的相關語句的用法,豈不美哉?)


create table city1(
city_id smallint(5) unsigned not null auto_increment,
city varchar(50) not null,
country_id smallint(5) unsigned not null,
primary key(city_id)
)
select city_id,city,country_id from city limit 3; 
-- 從city表中抽出前三條記錄放入新建的city1表

create table country1(
country_id smallint(5) unsigned not null auto_increment,
country varchar(50) not null,
primary key(country_id)
)
select country_id,country from country limit 2;
-- 從country表中抽出前兩條記錄放入新建的country1表
)

創建完成後的表是這樣的:

  1. City1表
    在這裏插入圖片描述
  2. country1表
    在這裏插入圖片描述

那麼下面就開始學習下如何進行連接查詢吧

交叉連接

交叉連接(Corss Join)也稱笛卡爾積,是將所連接的表進行笛卡爾積的運算。
假設交叉連接的表有A,B兩表,A表有xx行記錄,B表有yy行記錄,此時將返回xyx*y行記錄。

select * from city1,country1; 
-- 等價於 select * from city1 join country1;

在這裏插入圖片描述

內連接

內連接(Inner Join)是通過定義連接的表內數據之間的關係進行查詢

select * from <連接的表> inner join <被連接的表> on <條件表達式>;

:觀察到我們創建的兩張表其共同字段 country_id 並沒有相同值,因此我們必須修改一張表的數據以使其滿足連接需要

update city1 set country_id = '1' where (city_id='1');

更改後的 City1 表的數據是這樣的:
在這裏插入圖片描述


此時我們進行內連接可以得到:

select * from city1 inner join country1 
on city1.country_id = country1.country_id;

在這裏插入圖片描述

外連接

外連接(Outer Join)是相對於內連接而言的,它不僅顯示符合條件的記錄,也顯示不符合條件的某張表的數據:

  • 左連接(Left Join):不僅顯示符合條件的記錄,也顯示不符合條件的左表的數據
select * from city1 left join country1 on city1.country_id = country1.country_id;
  • 右連接(Right Join):不僅顯示符合條件的記錄,也顯示不符合條件的右表的數據
select * from city1 right join country1 on city1.country_id = country1.country_id;

子查詢

有時候我們通過一次查詢並不能得到想要的結果,需要在一次查詢的基礎上再進行查詢,這就是所謂的子查詢
我們以 sakila數據庫的customer表和payment表 爲例,其數據如下:

  1. customer表
    在這裏插入圖片描述
  2. payment表
    在這裏插入圖片描述
    下面進入正題:

select * from customer where 
customer_id in (select customer_id from payment where amount>10); 
-- 支付額大於10的顧客信息(顧客支付表和顧客信息表的聯合查詢)
-- 試試下面這個康康有啥子區別?
/* select * from customer inner join payment on
customer.customer_id=payment.customer_id and payment.amount>10; */

在這裏插入圖片描述

select * from customer where 
exists (select customer_id from payment 
where payment.customer_id=customer.customer_id and amount>10); 
-- 效果同上,不同的是EXISTS先執行括號外語句
-- 這個不如上面那句簡單清晰,建議使用上面那個 

下面再介紹兩個常用的函數any()all()

select * from customer where 
customer_id < any(select distinct customer_id from payment where amount > 10); 
-- 小於任意一個編號即可,即<max()
select * from customer where 
customer_id < all(select distinct customer_id from payment where amount > 10); 
-- 小於所有的編號,即<min() 

聯合查詢

有時候我們需要將查詢到結果合併起來,這時候就需要用到聯合查詢Union

-- 聯合查詢 

select count(customer_id) from sakila.rental; -- 返回16045條結果 
select count(customer_id) from payment; -- 返回16050條結果 
select customer_id from rental union select customer_id from payment; 
-- 自動去重,返回599條結果
select customer_id from rental union all select customer_id from payment; 
-- 不去重,返回32093條結果
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章