数据库——数据查询语言

(3)数据查询语言DQL

  • 简称DQL——Data Query Language
  • 用来查询数据库中表的记录
  • 关键字:select,from,where

-------单表操作-------

A. 数据准备
# 数据准备 建表
CREATE TABLE product
(
	pid INT PRIMARY KEY,
	pname VARCHAR(20),
    price DOUBLE,
    category_id VARCHAR(32)
);

# 向表中插入数据
INSERT INTO product(pid,pname,price,category_id) VALUES(1,'联想',5000,'c001');
INSERT INTO product(pid,pname,price,category_id) VALUES(2,'海尔',3000,'c001');
INSERT INTO product(pid,pname,price,category_id) VALUES(3,'雷神',5000,'c001');
INSERT INTO product(pid,pname,price,category_id) VALUES(4,'杰克琼斯',800,'c002');
INSERT INTO product(pid,pname,price,category_id) VALUES(5,'真维斯',200,'c002');
INSERT INTO product(pid,pname,price,category_id) VALUES(6,'花花公子',440,'c002');
INSERT INTO product(pid,pname,price,category_id) VALUES(7,'劲霸',2000,'c002');
INSERT INTO product(pid,pname,price,category_id) VALUES(8,'香奈儿',800,'c003');
INSERT INTO product(pid,pname,price,category_id) VALUES(9,'相宜本草',200,'c003');
INSERT INTO product(pid,pname,price,category_id) VALUES(10,'面霸',5,'c003');
INSERT INTO product(pid,pname,price,category_id) VALUES(11,'好想你枣',56,'c004');
INSERT INTO product(pid,pname,price,category_id) VALUES(12,'香飘飘奶茶',1,'c005');
INSERT INTO product(pid,pname,price,category_id) VALUES(13,'海澜之家',1,'c002');
B. 基础查询
  • 格式:SELECT [DISTINCT] *|列名,列名 FROM 表 WHERE 条件

    • DISTINCT作用:去除查询结果中的重复行
  • 查询全部字段:SELECT * FROM product

  • 查询指定字段:SELECT pname, price FROM product

  • 查询计算字段:SELECT pname, price+10 FROM product

  • 注意

    • 对未知大小的表应先加LIMIT限制结果数量

      • 示例
      SELECT t.* FROM tywin.product t # 相当于给product写了一个别名t
      LIMIT 510
      
    • 字段较多时应避免使用SELECT *,明确指定所需字段

    • 可以先用DESC 表名查看表结构再编写查询

C. 条件查询

下面语句所写位置是在WHERE 条件中的 “条件” 位置

a. 比较查询
  • < ><=>==<>!=(后面两个均代表不等于)
b. 范围查询
  • BETWEEN……AND……:显示在某一区间的值(含头含尾)

  • IN(set):显示在in列表中的值

    • 示例:

      SELECT * FROM product WHERE price IN(200,800) # 查询商品价格是 200 或 800 的所有商品
      
c. 模糊查询
  • LIKE '张%' LIKE '_涛%':模糊查询,Like语句中,%代表零个或多个任意字符,_代表一个字符
d. 非空查询
  • IS NULLIS NOT NULL:判断是否为空
e. 逻辑查询
  • and:多个条件同时成立
  • or:多个条件任一成立
  • not:不成立
D、排序查询
  • 格式:SELECT * FROM 表名 ORDER BY 排序字段 ASC|DESC;
    • ASC:升序(默认)
    • DESC:降序
  • 示例
#使用价格排序(降序)
SELECT * FROM product ORDER BY price DESC;

# 在价格排序的基础上,以分类排序
SELECT * FROM product ORDER BY price DESC,category_id DESC;
E、聚合查询

使用聚合函数查询是纵向查询,它是对一列导致进行计算,然后返回一个单一的值;聚合函数会忽略空值

  • count():统计指定列不为NULL的记录行数

    • count(*):不会把null略过
    • count(字段名):会自动忽略为null的那一列(不会记录)
  • sum():计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0

  • max():计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算

  • min():计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算

  • avg():计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0

  • 示例(可以和分组联合使用)

    #查询商品总条数
    SELECT COUNT(*) FROM product;
    
    #查询价格大于200的商品的总条数
    SELECT COUNT(*) FROM product WHERE price>200;
    
    # 查询分类为‘c002’所有商品的平均价格
    SELECT AVG(price) FROM product WHERE category_id='c002';
    
F、分组查询

分组查询使之使用group by字句对查询信息进行分组

  • 格式:SELECT 字段1,字段2……FROM 表名 GROUP BY 分组字段 HAVING 分组条件(依据分组字段进行分组)
    • 其中having子语句,是用于在分组后对数据进行过滤的,作用类似于where条件
  • having和where区别、
    • having是在分组后对数据进行过滤,where是在分组前对数据进行过滤
    • having后面可以使用分组函数(统计函数),where后面不可以使用分组函数
  • 示例
# 统计各个分类商品的个数
SELECT category_i,COUNT(*) FROM product GROUP BY category_id;
# 统计各个分类商品的个数,且只显示个数大于1的信息
SELECT category_id,COUNT(*) FROM product GROUP BY category_is HAVING COUNT(*) > 1;
G、分页查询

由于数据量很大,显示屏长度有限,因此对数据需要采取分页显示方式

  • 格式:SELECT 字段1,字段2…… FROM 表名 LIMIT M, N;
    • M:整数,表示从第几条索引开始,计算方式(当前页-1)*每页显示条数
    • N:整数,表示查询多少条数据
  • 示例
SELECT * FROM product LIMIT 0,5;#输出0,1,2,3,4这五行

-------多表操作-------

A、表与表之间的关系
  • 一对多关系
    • 建表原则:在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键
B、外键约束

现在又两张表“分类表”和“商品表”,为了表明商品属于哪个分类,通常情况下,我们将在商品表上添加一列,用于存放分类cid的信息,此列称为:外键

  • 特点
    • 从表外键的值是对主表主键的引用
    • 从表外键类型,必须与主表主键类型一致
  • 优点
    • 在插入数据时,保证了数据的准确性
    • 在删除数据时,保证了数据的完整性
# 创建分类表
CREATE TABLE category(
	cid VARCHAR(20) PRIMARY KRY,
    cname VARCHAR(100),
);

# 创建商品表(添加外键约束)
CREATE TABLE products(
	pid VARCHAR(20) PRIMARY KEY,
    pname VARCHAR(20),
    price DOUBLE,
    category_id VARCHAR(32), 
	CONSTRAINT FOREING KEY(category_cid) REFERENCES category(cid) # 添加的外键约束
);
constraint foreing

注意最后一句的写法:CONSTRAINT FOREING KEY(category_cid) REFERENCES category(cid) [外键KEY(category)指向category(cid)]

  • 示例
category
cid
cname
products
pid
name
price

在添加了外键约束之后

category
cid
cname
products
pid
name
price
category_id

其中“分类表category”称为:主表,“cid“称为主键,”商品表products“称为从表,”category_id“称为外键。我们是通过朱标的主键和从的外键来描述主外键关系(通过外键可以将两张表连接起来)

  • 删除指定分类

    • 从表中引用了主表中的数据,则主表中的数据是不可被删除的
    DELETE FROM products WHERE category_id = 'c001';
    DELETE FROM category WHERE cid = 'c001';# 如果仅执行这句语句,会报错,因为分类被商品使用,所以在这之前必须执行第一句代码
    
    • 主表中没有数据,从表外键也无法被插入
C、多表查询
  • 交叉连接查询(得到的是两个表的乘积)

    • 语法:select * from A,B
  • 交集运算:内连接查询(其中使用的关键字inner join – inner可以省略)

    • 语法(显示内连接):select * from A inner join B on 条件;
  • 差集运算:外连接查询(其中使用的关键字outer join – outer 可以省略)

    • 左连接(left outer join=left join
      • 语法:select * from A left outer join B on 条件;
    • 右连接(right outer join=right join
      • 语法:select * from A right outer join B on 条件;
  • 示例

--数据准备
# 创建hero表
CREATE TABLE hero(
	hid Int PRIMARY KEY,
    hname VARCHAR(255),
    kongfu_id INT
);

# 创建kongfu表
CREATE TABLE kongfu(
	kid INT PRIMARY KEY,
    kname VARCHAR(255)
);

# 插入hero数据
INSERT INTO hero VALUES(1,'鸠摩智',9),(3,'乔峰',1),(4,'虚竹',4),(5,'段誉',12);

# 插入kongfu数据
INSERT INTO kongfu VALUES(1,'降龙十八掌'),(2,'乾坤大挪移'),(3,'猴子偷桃'),(4,'天山折梅手')

# 内连接
SELECT hname,kname FROM hero INNER JOIN kongfu ON hero.kongfu_id = kongfu.kid;
# 如果直接写join 没有其他修饰词 就是内连接
SELECT hname,kname FROM hero JOIN kongfu ON hero.kongfu_id = kongfu.kid;
# 左外连接
SELECT hname,kname FROM hero LEFT OUTER JOIN kongfu ON hero.kongfu_id = kongfu.kid;
# 右外连接
SELECT hname, kname FROM hero RIGHT OUTER JOIN kongfu ON hero.kongfu_id = kongfu.kid;
  • 输出结果

    • 内连接

      hname kname
      乔峰 降龙十八掌
      虚竹 天山折梅手
    • 左连接

      hname kname
      乔峰 降龙十八掌
      虚竹 天山折梅手
      鸠摩智
      段誉
    • 右连接

      hname kname
      乔峰 降龙十八掌
      虚竹 天山折梅手
      乾坤大挪移
      猴子偷桃
D、子查询
  • 定义:一条select语句结果作为另一条select语法一部分(查询条件,查询结果,表等)

  • 示例1:作为条件

SELECT * FROM products p # 起别名
WHERE p.category_id = (SELECT c.cid FROM category c WHERE c.cname='化妆品')
  • 示例2:作为一张表
    • 注意:子查询作为一张表来使用的时候,一定需要取一个别名
# 作为另一张图(交叉连接)
SELECT * FROM products p,(SELECT * FROM category WHERE cname='化妆品') c WHERE p.category_id=c.cid;

# 一张表 条件筛选
SELECT * FROM products p WHERE p.category_id in (SELECT c.cid FROM category c WHERE c.cname='化妆品' or c.name='家电');
E、自查询

左表和右表是同一张表,进行join,根据连接查询条件查询两个表中的数据

  • 注意:子查询部分一定要取一个别名
CREATE TABLE tb_areas(
	id VARCHAR(30) NOT NULL PRIMARY KEY,
    title VARCHAR(30),
    pid VARCHAR(30)
);

# 写入数据
INSERT INTO tb_areas(id, title, pid) VALUES('1','广东省','null');
INSERT INTO tb_areas(id, title, pid) VALUES('2','河南省','null');
INSERT INTO tb_areas(id, title, pid) VALUES('3','深圳市','1');
INSERT INTO tb_areas(id, title, pid) VALUES('4','广州市','1');
INSERT INTO tb_areas(id, title, pid) VALUES('5','南山区','3');
INSERT INTO tb_areas(id, title, pid) VALUES('6','宝安区','3');
INSERT INTO tb_areas(id, title, pid) VALUES('7','越秀区','4');
INSERT INTO tb_areas(id, title, pid) VALUES('8','天河区','4');

# ①(c city p province)
SELECT p.title, c.title FROM tb_areas as c JOIN tb_areas as p on c.pid = p.id;
# ②只剩下省份,并呈现id
SELECT p.title, c.title, c.id FROM tb_areas as c JOIN tb_areas as p on c.pid=p.id WHERE p.title="广东省";
# s(c city p province d distinct) 想将省市区放在一张表中
SELECT a.province 省, a.city 市, d.title 区 FROM
(SELECT p.title province, c.title city, c.id FROM tb_areas as c JOIN tb_areas AS p ON c.pid=p.id WHERE p.title="广东省") a JOIN tb_areas d ON d.pid = a.id;

输出

p.title c.title
广东省 深圳市
广东省 广州市
深圳市 南山区
深圳市 宝安区
广州市 越秀区
广州市 天河区

p.title c.title id
广东省 深圳市 3
广东省 广州市 4

广东省 深圳市 南山区
广东省 深圳市 宝安区
广东省 广州市 越秀区
广东省 广州市 天河区

(4)数据控制语言

  • 简称DCL——Data Control Language
  • 用来定义数据库的访问权限和安全级别及创建用户

你可能感兴趣的:(SQL数据库,数据库)