DQL(Date Query Language)資料庫查詢語句

HuDu發表於2020-07-27

DQL

  • 所有的查詢操作都用它 select
  • 簡單的查詢和複雜的查詢都能做
  • 資料庫中最核心的語言
  • 使用頻率最高的語句

資料庫準備

create database if not exists `school2`;
-- 建立一個school資料庫
use `school2`;-- 建立學生表
drop table if exists `student`;

create table `student`(
    `studentno` int(4) not null comment '學號',
    `loginpwd` varchar(20) default null,
    `studentname` varchar(20) default null comment '學生姓名',
    `sex` tinyint(1) default null comment '性別,0或1',
    `gradeid` int(11) default null comment '年級編號',
    `phone` varchar(50) not null comment '聯絡電話,允許為空',
    `address` varchar(255) not null comment '地址,允許為空',
    `borndate` datetime default null comment '出生時間',
    `email` varchar (50) not null comment '郵箱賬號允許為空',
    `identitycard` varchar(18) default null comment '身份證號',
    primary key (`studentno`),
    unique key `identitycard`(`identitycard`),
    key `email` (`email`)
)engine=myisam default charset=utf8;
-- 建立年級表
drop table if exists `grade`;
create table `grade`(
    `gradeid` int(11) not null auto_increment comment '年級編號',
  `gradename` varchar(50) not null comment '年級名稱',
    primary key (`gradeid`)
) engine=innodb auto_increment = 6 default charset = utf8;

-- 建立科目表
drop table if exists `subject`;
create table `subject`(
    `subjectno`int(11) not null auto_increment comment '課程編號',
    `subjectname` varchar(50) default null comment '課程名稱',
    `classhour` int(4) default null comment '學時',
    `gradeid` int(4) default null comment '年級編號',
    primary key (`subjectno`)
)engine = innodb auto_increment = 19 default charset = utf8;

-- 建立成績表
drop table if exists `result`;
create table `result`(
    `studentno` int(4) not null comment '學號',
    `subjectno` int(4) not null comment '課程編號',
    `examdate` datetime not null comment '考試日期',
    `studentresult` int (4) not null comment '考試成績',
    key `subjectno` (`subjectno`)
)engine = innodb default charset = utf8;
-- 插入科目資料
insert into `subject`(`subjectno`,`subjectname`,`classhour`,`gradeid`)values
(1,'高等數學-1',110,1),
(2,'高等數學-2',110,2),
(3,'高等數學-3',100,3),
(4,'高等數學-4',130,4),
(5,'C語言-1',110,1),
(6,'C語言-2',110,2),
(7,'C語言-3',100,3),
(8,'C語言-4',130,4),
(9,'Java程式設計-1',110,1),
(10,'Java程式設計-2',110,2),
(11,'Java程式設計-3',100,3),
(12,'Java程式設計-4',130,4),
(13,'資料庫結構-1',110,1),
(14,'資料庫結構-2',110,2),
(15,'資料庫結構-3',100,3),
(16,'資料庫結構-4',130,4),
(17,'C#基礎',130,1);
-- 插入學生資料 其餘自行新增 這裡只新增了2行
insert into `student` (`studentno`,`loginpwd`,`studentname`,`sex`,`gradeid`,`phone`,`address`,`borndate`,`email`,`identitycard`)
values
(1000,'123456','張偉',0,2,'13800001234','北京朝陽','1980-1-1','text123@qq.com','123456198001011234'),
(1001,'123456','趙強',1,3,'13800002222','廣東深圳','1990-1-1','text111@qq.com','123456199001011233');

-- 插入成績資料  這裡僅插入了一組,其餘自行新增
insert into `result`(`studentno`,`subjectno`,`examdate`,`studentresult`)
values
(1000,1,'2013-11-11 16:00:00',85),
(1000,2,'2013-11-12 16:00:00',70),
(1000,3,'2013-11-11 09:00:00',68),
(1000,4,'2013-11-13 16:00:00',98),
(1000,5,'2013-11-14 16:00:00',58);

-- 插入年級資料
insert into `grade` (`gradeid`,`gradename`) values(1,'大一'),(2,'大二'),(3,'大三'),(4,'大四'),(5,'預科班');

查詢指定欄位

select * from student;

-- 查詢指定欄位
select `studentno`,`studentname` from student;

-- 別名,給結果起一個名字,也可以給表起別名 as 可以省略
select `studentno` as 學號,`studentname` 姓名 from student as s;

-- 函式 concat(a,b)
select concat('姓名:',studentname) as 新名字 from student;

DQL(Date Query Language)資料庫查詢語句

去重 distinct

-- 查詢哪些同學參加了考試,成績
select * from result;
-- 查詢了哪些同學參加了考試
select studentno from result
-- 去除select查詢出來的結果中重複的資料,重複的資料只顯示一條
select distinct studentno from result;

資料庫的列(表示式)

select version()    -- 查詢系統版本號(函式)
select 100*3-1 as 計算結果    -- 用來計算(表示式)
select @@auto_increment_increment    -- 查詢自增的步長(變數)
-- 學員考試成績加一分
select studentno,studentresult+1 as '提分後' from result;

資料庫中的表示式:文字值,列,Null,函式,計算表示式,系統變數。。。

select 表示式 from 表名

where條件子句

作用:檢索資料中符合條件的資料
搜尋語句由一個或多個表示式組成,結果為布林值

邏輯

運算子 語法 描述
and && a and b 邏輯與,兩個都為真,結果為真
or || a or b 邏輯或,一個為真,結果為真
not ! not a 邏輯非 ,真為假,假為真

儘量使用英文字母

例子

select studentno,studentresult from result where studentresult >= 95 and studentresult <= 100;

-- 模糊查詢(區間)
select studentno,studetnresult from result where studentresult between 95 and 100;

-- !=  和 not
select studentno,studentresult from result wehre sutdentno != 1000;
select studentno,studentresult from result where not student = 1000;

模糊查詢:比較運算子

運算子 語法 描述
is null a is null 如果操作符為null,結果為真
is not null a is not null 如果操作符不為null,結果為真
between a berween a and c 若a在b和c之間,則結果為真
like a like b SQL匹配,如果a匹配b,則結果為真
in a in(a1,a2,a3…) 假設a在a1,或者a2…其中的某一個值中,結果為真
-- 查詢姓劉的同學 like結合 %(代表0到任意個字元) _(一個字元)
select studentno,studentname from student where studentname like '劉%'

-- 查詢姓劉的同學,名字後面只有一個字
select studentno,studentname from student where studentname like '劉_'

-- 查詢名字中有嘉的同學
select studentno,studentname from student where studentname like '%劉%'
-- 查詢1001,1002,1003學號的學員,in裡面是具體的一個或多個值
select studentno,studentname from student where studentno in (1001,1002,1003);

-- 查詢在北京的學生
select studentno,studentname from student where address in ('北京');

-- 查詢地址為空的學生 null ''
select studentno,studentname from student where address = '' or address is null;

聯表查詢

join 對比

DQL(Date Query Language)資料庫查詢語句

-- 查詢參加了考試的同學(學號,姓名,科目編號,分數)
select * from sutdent
select * from result

/*
1. 分析需求,分析查詢的欄位來自哪些表
2.確定使用那種連線查詢
確定交叉點(這兩個表哪些資料是相同的)
判斷條件:學生表中的studentno = 成績表 studentno
*/

select s.studentno,studentname,subjectno,studentresult
from student s
inner join result r
where s.sutdentno = r.studentno

-- Right Join
select s.studentno,studentname,subjectno,studentresult
from student s
right join result r
on s.studentno = r.studentno

-- Left Join
select s.studentno,studentname,subjectno,studentresult
from student s
Left join result r
on s.studentno = r.studentno
操作 描述
inner join 如果表中至少一個匹配,就返回行
left join 即使右表中沒有匹配,也會從左表中返回所有的值
right join 即使左表中沒有匹配,也會從右表中返回所有的值
  • join(連線的表) on(判斷的條件) 連線查詢
  • where 等值查詢
-- 查詢缺考的同學
select s.studentno,studentname,subjectno,studentresult
from student s
Left join result r
on s.studentno = r.studentno
where studentresult=null
  • 要求:查詢了參加考試的同學資訊:學號,學生姓名,科目名,分數
select s.studentno,studentname,subjectname,studentresult
from student s
right join result r
on r.studentno = s.studentno
inner join subject sub
on r.subjectno = sub.subjectno

自連線

先建立一個表

CREATE TABLE `school`.`category`( 
`categoryid` INT(3) NOT NULL COMMENT 'id', 
`pid` INT(3) NOT NULL COMMENT '父id 沒有父則為1', 
`categoryname` VARCHAR(10) NOT NULL COMMENT '種類名字', 
PRIMARY KEY (`categoryid`) 
) ENGINE=INNODB CHARSET=utf8 COLLATE=utf8_general_ci;

INSERT INTO `school`.`category` (`categoryid`, `pid`, `categoryname`) VALUES ('2', '1', '資訊科技');
insert into `school`.`CATEGOrY` (`categoryid`, `pid`, `categoryname`) values ('3', '1', '軟體開發');
insert into `school`.`category` (`categoryid`, `PId`, `categoryname`) values ('5', '1', '美術設計');
insert iNTO `School`.`category` (`categoryid`, `pid`, `categorynamE`) VAlUES ('4', '3', '資料庫');
insert into `school`.`category` (`CATEgoryid`, `pid`, `categoryname`) values ('8', '2', '辦公資訊');
insert into `school`.`category` (`categoryid`, `pid`, `CAtegoryname`) values ('6', '3', 'web開發');
inserT INTO `SCHool`.`category` (`categoryid`, `pid`, `categoryname`) valueS ('7', '5', 'ps技術');
  • 查詢父子資訊
    自連線就是把一張表看成兩張不一樣的表
    select a.categoryname as '父欄目',b.categoryname as '子欄目'
    from category as a,category as b
    where a.catrgoryid = b.pid;

select 完整語法:

select [all | distinct]
{* | table.* | [table.field1[as alias1][,table.field2[as alias2]][,...]]}
from table_name [as table_alias]
    [left | right | inner join table_name2]    -- 聯合查詢
    [where ... ]    -- 自定結果需滿足的條件
    [group by]    -- 指定結果按照那幾個欄位來分組
    [having]    -- 過濾分組的記錄必須滿足的次要條件
    [order by ...]    -- 指定查詢記錄按一個或多個條件排序
    [limit {[offset,]row_count | row_countOFFSET offset}];    -- 指定查詢的記錄從哪條至哪條

分頁和排序

limit和order by

  • 排序:升序 ASC,降序DESC
select s.studentno,studentname,subjectname,subjectresult
from student s
inner join result r
on s.studentno = r.studentno
inner join subject sub
on r.subjectno = sub.subjectno
where subjectname = '資料結構-1'
order by subjectresult asc
  • 分頁作用
    緩解資料庫壓力,給人更好的體驗,瀑布流

每頁只顯示五條資料
語法:limit 起始值,頁面的大小
網頁應用:當前,總頁數,頁面的大小

select s.studentno,studentname,subjectname,subjectresult
from student s
inner join result r
on s.studentno = r.studentno
inner join subject sub
on r.subjectno = sub.subjectno
where subjectname = '資料結構-1'
order by subjectresult asc
limit 0,5;

-- 第一頁 limit 0,5
-- 第二頁 limit 5,5
-- 第n頁 limit 5n-5,5
-- 資料總數/頁面大小+1 = 總頁數

子查詢和巢狀查詢

where(這個值是計算出來的)
本質:在where語句中巢狀一個子查詢語句

查詢資料庫結構-1所有的考試結果(學號,科目名字,成績)

-- 方式一:使用連線查詢
select sutdentno,r.subjectno,studentresult
from result r
inner join subject sub
on r.subjectno = sub.subjectno
where subjectname = '資料庫結構-1'
order by studentno desc

-- 方式二:使用自查詢(由裡及外)
select studentno,subjectno,studentresult
from result
where subjectno = (
    select subjectno from subject where subjectname = '資料庫結構-1'
)

-- 查詢所有資料庫結構-1的學生的編號
select subjectno from subject where subjectname = '資料庫結構-1'
-- 查詢課程為高等數學-2 並且分數不小於80 的同學的學號和姓名
select s.studentno,studentname
from student s
inner join result r
on s.studentno = r.studentno
inner join subject sub
on sub.subjectno = r.subjectno
where subjectname = '高等數學-2' and studentresult>=80;

-- 子查詢
select studentno,studentname
from student s
inner join result r
on r.studentno = s.studentno
where studentresult >= 80 and studentno = (
    select subjectno from subject where subjectname='高等數學-2'
)

-- 再改造
select studentno,studentname from student where studentno in(
    select student from result where studentresult>80 and subjectno = (
        select subjectno from subject where subjectname = ' 高等數學-2'
    )
)

MySQL 函式

  • 常用函式
-- 數學運算子

-- 絕對值
select ABS(-8)
-- 向上取整,返回10
SELECT CEILING(9.4)
-- 向下取整,返回9
SELECT FLOOR(9.4)
-- 返回0~1之間的隨機數
SELECT RAND()
-- 判斷一個數的符號:0-0,負數- -1,正數 1
SELECT SIGN(-10)
-- 字串函式
SELECT CHAR_LENGTH('測試')
-- 合併字串
SELECT CONCAT('I ','am ','chinese')
-- 替換插入字串,第一個從1開始
SELECT INSERT('hello world!',7,11,'haha')
-- 小寫字母
SELECT LOWER('HaHa')
-- 大些字母
SELECT UPPER('aaa')
-- 返回字母第一次出現的索引,不區分大小寫
SELECT INSTR('HuDu','d')
-- 替換出現的指定的字串
SELECT REPLACE('hello','e','a')
-- 返回指定的字串,擷取開始位置,擷取幾個
SELECT SUBSTR('hello world',7,5)
-- 反轉字串
SELECT REVERSE('hello')

例子

-- 查詢姓周的同學,姓改為 鄒
select replace(studentname,'周','鄒') from student
where studentname like '周'
-- 時間和日期函式

-- 當前日期
SELECT CURRENT_DATE()
-- 獲取當前的日期
SELECT CURDATE()
-- 獲取當前的時間
SELECT NOW()
-- 本地時間
SELECT LOCALTIME()
-- 系統時間
SELECT SYSDATE()

SELECT YEAR(NOW())
SELECT MONTH(NOW())...

SELECT SYSTEM_USER()
SELECT USER()
SELECT VERSION()
  • 聚合函式(常用)
函式名稱 描述
count() 計數
sum() 求和
avg() 平均值
max() 最大值
min() 最小值
-- count(指定列),會忽略所有的 null 值
SELECT COUNT(studentname) FROM student;
-- count(*),不會忽略 null 值,本質計算行數
SELECT COUNT(*) FROM student;
-- count(1),不會忽略 null 值,本質計算行數
SELECT COUNT(1) FROM student;
SELECT SUM(studentresult) as '總和' FROM result;
SELECT AVG(studentresult) as '總和' FROM result;
SELECT MAX(studentresult) as '總和' FROM result;
SELECT MIN(studentresult) as '總和' FROM result;
-- 查詢不同課程的平均值,最高分,最低分,平均分大於80
select subjectname,avg(studentresult) 平均分,max(studentresult),min(studentresult)
from result r
inner join subject sub
on r.subjectno = sub.subjecton
group by r.subjectNo    -- 通過什麼欄位來分組
having 平均分>80
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章