第四章 SQL与关系数据库基本操作
SQL概述
结构化查询语言(Structured Query Language, SQL)是专门用来与数据库通信的语言,它可以帮助用户操作关系数据库。
SQL的特点
- SQL不是某个特定数据库供应商专有的语言;
- SQL简单易学;
- SQL强大、灵活,可以进行非常复杂和高级的数据库操作;
SQL的组成
- 数据查询:核心功能;
- 数据定义;
- 数据操纵;
- 数据控制;
数据定义语言
英文:Data Definition Language, DDL
- CREATE:创建 数据库或数据库对象;
- ALTER:对数据库或数据库对象进行 修改;
- DROP:删除 数据库或数据库对象;
数据操纵语言
英文:Data Manipulation Language, DML
- SELECT:从表或视图中 检索 数据;
- INSERT:将数据 插入 到表或视图中;
- UPDATE:修改 表或视图中的数据;
- DELETE:从表或视图中 删除 数据;
数据控制语言
英文:Data Control Language, DCL
- GRANT:用于 授予 权限;
- REVOKE:用于 收回 权限;
嵌入式和动态SQL规则
嵌入式和动态SQL规则规定了SQL语句在高级语言程序设计中使用的规范方法,以便适应较为复杂的应用。
SQL调用和会话规则
SQL调用:SQL例程、调用规则
MySQL预备知识
MySQL使用基础
MySQL是 关系数据库管理系统(RDBMS)
优点:体积小、速度快、开放源代码、遵循GPL
构架方式:LAMP、WAMP
L:Linux、W:Windows、A:Apache、M:MySQL、P:PHP
MySQL扩展语言要素
常量
- 字符串常量;
- 数值常量;
- 十六进制常量;
- 时间日期常量;
- 位字段值;
- 布尔值;
- NULL值;
变量
- 用户变量:用户变量前常添加 一个@,用于将其与列名区分开;
- 系统变量:大多数系统变量应用于其他SQL语句中时,必须在系统变量前添加 两个@;
运算符
类型 | |
---|---|
算术运算符 | +、-、*、/、%(求模) |
位运算符 | &(与)、|(或)、^(异或)、~(取反)、>>(位右移)、<<(位左移) |
比较运算符 | =(等于)、>(大于)、<(小于)、>=(大于等于)、<=(小于等于)、<>(不等于)、!=(不等于)、<=>(相等或都等于等) |
逻辑运算符 | NOT或!(逻辑非)、AND或&&(逻辑与)、OR或||(逻辑或)、XOR(逻辑异或) |
表达式
- 字符型表达式;
- 数值型表达式;
- 日期型表达式;
内置函数
类型 | |
---|---|
数学函数 | ABS() |
聚合函数 | COUNT() |
字符串函数 | ASCⅡ() |
日期和时间函数 | NOW() |
加密函数 | ENCODE() |
控制流程函数 | IF() |
格式化函数 | FORMAT() |
类型转换函数 | CAST() |
系统信息函数 | USER() |
数据定义
数据库模式定义
创建数据库
使用 CREATE DATABASE
或 CREATE SCHEMA
语句。
使用 IF NOT EXISTS
校验数据库不存在。
-- 伪代码:
-- CREATE {DATABASE | SHCEMA} [IF NOT EXISTS] db_name;
CREATE DATABASE IF NOT EXISTS db_name;
查看数据库
使用 SHOW DATABASES
或 SHOW SCHEMAS
语句。
使用 LIKE
关键字用于匹配指定的数据库名称。
使用 WHERE
从句用于指定数据库名称查询范围的条件。
-- 伪代码:
-- SHOW {DATABASES | SHCEMAS} [LIKE 'pattern' | WHERE expr];
-- LIKE 关键字
SHOW DATABASES LIKE 'pattern';
-- WHERE 从句
SHOW DATABASES WHERE expr;
注意:
DATABASES
是 复数
选择数据库
使用 USE
关键字。
USE db_name;
修改数据库
使用 ALTER DATABASE
语句
ALTER DATABASE db_name;
删除数据库
使用 DROP DATABASE
或 DROP SCHEMA
语句。
使用 IF EXISTS
校验数据库存在。
-- 伪代码:
-- DROP {DATABASE | SHCEMA} [IF EXISTS] db_name;
DROP DATABASE IF EXISTS db_name;
表定义
数据表是关系数据库中最重要、最基本的数据对象,也是数据存储的基本单位。
创建表
使用 CREATE TABLE
语句。
使用 TEMPORARY
关键字,声明当前表是否为 临时表。
使用 AUTO_INCREMENT
关键字,声明当前字段为 自增属性。只有在数据类型为 INT 时才有效。
使用 PRIMARY KEY
关键字,声明当前表的 主键。
数据类型,有以下:
- 整型:
INT
- 浮点型:
DOUBLE
- 布尔型:
BOOL
- 日期型:
DATE
- 时间戳:
TIMESTAMP
- 时间型:
TIME
- 定长字符型:
CHAR
- 可变长字符型:
VARCHAR
-- 伪代码:
-- CREATE [TEMPORARY] TABLE tbl_name
-- (
-- 字段名 数据类型 [列级完整性约束] [默认值],
-- 表级完整性约束
-- )[ENGINT=引擎类型];
CREATE TABLE customers
(
cust_id INT NOT NULL AUTO_INCREMENT,
cust_name CHAR(50) NOT NULL,
cust_sex CHAR(1) NOT NULL DEFAULT '0',
cust_address CHAR(50) NULL,
cust_contact CHAR(50) NULL,
PRIMARY KEY(cust_id)
);
更新表
使用 ALTER TABLE
语句。
-- 伪代码:
-- ALTER TABLE tbl_name 子句
ALTER TABLE db_name.tbl_name
ADD COLUMN col_name int NOT NULL DEFAULT 1;
注意:以下的的
ADD
、CHANGE
等都为ALTER TABLE
的子句。
使用 ADD
关键字,对表 增加新列。使用 AFTER
关键字,可以指定列添加在哪一列之后。
-- 伪代码:
-- ADD COLUMN 列名 数据类型 [列级完整性约束] [默认值] [插入位置]
ALTER TABLE db_name.tbl_name
ADD COLUMN col_name CHAR(50) NOT NULL DEFAULT 'name' AFTER before_col_name;
使用 CHANGE
关键字,修改表中列的 名称或数据类型。
-- 伪代码:
-- CHANGE COLUMN 旧列名 新列名 数据类型 [列级完整性约束] [默认值]
ALTER TABLE db_name.tbl_name
CHANGE COLUMN old_col_name col_name CHAR(50) NOT NULL DEFAULT 'name';
使用 ALTER
关键字,修改或删除表中列的 默认值。
-- 伪代码:
-- ALTER COLUMN 列名 SET DEFAULT {新默认值 | NULL}
ALTER TABLE db_name.tbl_name
ALTER COLUMN col_name SET DEFAULT 'value';
使用 MODIFY
关键字,修改指定列的 数据类型。使用 FIRST
关键字将列设置为表的第一列。
-- 伪代码:
-- MODIFY COLUMN 列名 数据类型 [列位置]
ALTER TABLE db_name.tbl_name
MODIFY COLUMN col_name INT FIRST;
使用 DROP
关键字,删除 表中多个列。
-- 伪代码:
-- DROP COLUMN 列名1 [,列名2,...,列名n]
ALTER TABLE db_name.tbl_name
DROP COLUMN col_name;
使用 RENAME TO
关键字,为表 重命名。
-- 伪代码:
-- RENAME TO db_name.tbl_name
ALTER TABLE db_name.tbl_name
RENAME TO db_name.tbl_new_name;
重命名表
使用 RENAME TABLE TO
语句。
-- 伪代码:
-- RENAME TABLE 老名字 TO 新名字
RENAME TABLE db_name.old_name TO db_name.new_name;
删除表
使用 DROP TABLE
语句。
-- 伪代码:
-- DROP [TEMPORARY] TABLE [IF EXISTS] 表名 [, 表名1, 表名2, ..., 表名n]
DROP TABLE db_name.table_name;
查看表
使用 SHOW TABLE
语句,展示数据库中的表。
-- 伪代码:
-- SHOW [FULL] TABLE [{FROM | IN} 数据库名] [LIKE 'pattern' | WHERE expr];
SHOW TABLE FROM db_name;
使用 SHOW COLUMNS
或 DESCRIBE | DESC
显示指定表的接口。
-- 伪代码:
-- SHOW [FULL] COLUMNS {FROM | IN} 表名 [{FROM | IN} 数据库名] [LIKE 'pattern' | WHERE expr];
-- {DESCRIBE | DESC} 表名 [列名 | wild];
SHOW COLUMNS FROM tbl_name FROM db_name;
索引定义
索引是提高数据文件访问效率的有效方法。
索引存在的 弊端:
- 索引是以文件的形式存储的,如果有大量的索引,索引文件可能比数据文件更快达到最大的文件尺寸;
- 索引在提高查询速度的同时,会降低更新表的速度;
索引的 分类:
- 普通索引:
INDEX
或KEY
; - 唯一性索引:
UNIQUE
; - 主键:
PRIMARY KEY
;
创建索引
使用 CREATE INDEX
语句。
使用 ASC
或 DESC
指定 排序方式。
-- 伪代码:
-- CREATE [UNIQUE] INDEX 索引名 ON 表名
-- (
-- 列名1[(列前几字符长度)] [排序方式]
-- [, 列名2[(列前几字符长度)] [排序方式]]
-- [..., 列名n]
-- );
-- 单列索引
CREATE INDEX index_customers ON db_name.tbl_name(col_name(3) ASC);
-- 组合索引
CREATE INDEX index_customers ON db_name.tbl_name(col_name_1, col_name_2);
在 CREATE TABLE
中创建索引。
-- 伪代码:
-- CREATE TABLE 表名
-- (
-- 字段名 数据类型 [列级完整性约束] [默认值],
-- PRIMARY KEY(列名),
-- [INDEX | KEY] 普通索引名(列名),
-- UNIQUE [INDEX | KEY] 唯一性索引名(列名),
-- FOREIGN KEY 外键名(列名),
-- );
CREATE TABLE tbl_name
(
seller_id INT NOT NULL,
seller_name CHAR(50) NOT NULL,
seller_type CHAR(50) NOT NULL,
sales INT NULL,
PRIMARY KEY(seller_id, seller_type),
INDEX index_sales(sales)
);
在 ALTER TABLE
中使用 ADD
子句,创建索引。
-- 伪代码:
-- ALTER TABLE 表名
-- ADD PRIMARY KEY(列名)
-- ADD [INDEX | KEY] 普通索引名(列名)
-- ADD UNIQUE [INDEX | KEY] 唯一性索引名(列名)
-- ADD FOREIGN KEY 外键名(列名)
ALTER TABLE tbl_name
ADD INDEX index_seller_name(seller_name);
查看索引
使用 SHOW INDEX
语句。
-- 伪代码:
-- SHOW [INDEX | INDEXES | KEYS]
-- {FROM | IN} 表
-- [{FROM | IN} 数据库]
-- [WHERE 查询条件]
SHOW INDEXES FROM tbl_name;
删除索引
使用 DROP INDEX
语句。
-- 伪代码:
-- DROP INDEX 索引名 ON 表名
DROP INDEX index_seller_name ON tbl_name;
在 ALTER TABLE
中使用 DROP
子句,删除索引。
-- 伪代码:
-- ALTER TABLE 表名
-- DROP PRIMARY KEY
-- DROP [INDEX | KEY] 普通索引名
-- DROP FOREIGN KEY 外键名
ALTER TABLE tbl_name
DROP INDEX index_seller_name(seller_name);
实操中
DROP PRIMARY KEY
会报错。
数据更新
插入数据
使用 INSERT...VALUES
语句,插入单行或多行元组数据。
-- 伪代码:
-- INSERT INTO 表名[(列名, ...)]
-- {VALUES | VALUE}({expr | DEFAULT}, ...)[, ({expr | DEFAULT}, ...), ..., ({expr | DEFAULT},...)]
INSERT INTO tbl_name
VALUES(0, 'chen.chen.chen', DEFAULT, 'male', NULL),
(0, 'luo.luo.luo', DEFAULT, 'female', NULL);
expr
:表示一个常量、变量或一个表达式,也可以是空值NULL
DEFAULT
:关键字,表示使用该列的默认值
使用 INSERT...SET
语句,插入部分列值数据。
-- 伪代码:
-- INSERT INTO 表名
-- SET 列名1={expr | DEFAULT}[, 列名2={expr | DEFAULT}, ..., 列名n={expr | DEFAULT}]
INSERT INTO tbl_name
SET cust_name='chen.chen.chen', cust_sex=DEFAULT;
使用 INSERT...SELECT
语句,从一个表复制数据,然后把数据插入到一个已存在的表中。
-- 复制所有列,伪代码:
-- INSERT INTO 插入的表
-- SELECT * FROM 提取的表;
-- 复制指定列,伪代码:
-- INSERT INTO 插入的表 (插入的列, ...)
-- SELECT (提取的列, ...)
-- FROM 提取的表;
INSERT INTO student (teacher_name, teacher_contact)
SELECT (t_name, t_contact)
FROM teacher;
插入操作要求两边的操作列保持一致(字段类型、字段数量)。
删除数据
使用 DELETE
语句删除一行或多行数据。
-- 伪代码:
-- DELETE FROM 表名
-- [WHERE 需要删除语句的判断条件]
-- [ORDER BY ...]
-- [LIMIT 删除数量]
DELETE FROM tbl_name
WHERE cust_name='chen.chen.chen';
修改数据
使用 UPDATE
语句修改更新一个表中的数据。
-- 伪代码:
-- UPDATE 表名
-- SET 列名1={expr | DEFAULT}[, 列名2={expr | DEFAULT}, ..., 列名n={expr | DEFAULT}]
-- [WHERE 需要修改语句的判断条件]
-- [ORDER BY ...]
-- [LIMIT 修改数量]
UPDATE tbl_name
SET cust_name='luo.luo.luo'
WHERE cust_sex='female';
数据查询
查询语句
使用 SELECT
语句进行查询。
-- 伪代码:
-- [WHERE 查询条件]
-- [GROUP BY 分组条件]
-- [HAVING 指定组的选择条件]
-- [ORDER BY 排序方式]
-- [LIMIT 限制行数]
-- 选择指定的列
SELECT cust_name, cust_sex FROM tbl_name;
-- 选择全部的信息
SELECT * FROM tbl_name;
-- 定义并使用列的列名
SELECT cust_sex AS cust_gender FROM tbl_name;
聚合函数
聚合函数通常是数据库系统中一类系统 内置函数。
函数名 | 说明 |
---|---|
COUNT |
求组中项数,返回INT类型整数 |
MAX |
求最大值 |
MIN |
求最小值 |
SUM |
返回表达式中所有值的和 |
AVG |
求组中值的平均值 |
STD 或 STDDEV
|
返回给定表达式中所有值的标准值 |
VARIANCE |
返回给定表达式中所有制的方差 |
GROUP_CONCAT |
返回又属于一组的列值连接组合而成的结果 |
BIT_AND |
逻辑与 |
BIT_OR |
逻辑或 |
BIT_XOR |
逻辑异或 |
列的选择与指定
使用 CASE
表达式,替换查询结果集中的数据。
-- 伪代码:
-- CASE
-- WHEN 条件1 THEN 表达式1
-- WHEN 条件2 THEN 表达式2
-- ...
-- ELSE 表达式
-- END AS 列别名
SELECT cust_name,
CASE
WHEN cust_sex='male' THEN 'boy'
ELSE 'girl'
END AS cust_gender
FROM tbl_name;
多表连接查询
使用 FROM
子句完成对查询对象的指定。
交叉连接
使用 CROSS JOIN
完成交叉连接,又称笛卡尔积。
-- 伪代码:
-- SELECT * FROM 表1 CROSS JOIN 表2;
-- SELECT * FROM 表1, 表2;
SELECT * FROM tbl_name_1 CROSS JOIN tbl_name_2;
内连接
使用 INNER JOIN
完成内连接。这种连接方式称为 自连接。
在内连接的使用中,如果在 ON
子句的连接条件中使用运算符 =
,则此连接方式称为 等值连接。
-- 伪代码:
-- SELECT {* | 列名} FROM 表1
-- INNER JOIN 表2
-- ON 条件
SELECT * FROM tbl_student
INNER JOIN tbl_score
ON tbl_student.id=tb_sorce.student_id;
左外连接
使用 LEFT JOIN
完成左外连接。返回左表所有的行,右表没有匹配结果显示为 NULL
。
-- 伪代码:
-- SELECT {* | 列名} FROM 表1
-- LEFT JOIN 表2
-- ON 条件
SELECT * FROM tbl_student
LEFT JOIN tbl_score
ON tbl_student.id=tb_sorce.student_id;
右外连接
使用 RIGHT JOIN
完成右外连接。返回右表所有的行,左表没有匹配结果显示为 NULL
。
-- 伪代码:
-- SELECT {* | 列名} FROM 表1
-- RIGHT JOIN 表2
-- ON 条件
SELECT * FROM tbl_student
RIGHT JOIN tbl_score
ON tbl_student.id=tb_sorce.student_id;
条件查询(过滤数据行)
使用 WHERE
子句,进行(数据行)条件查询。
-- 伪代码:
-- SELECT * FROM 表名
-- WHERE 条件
SELECT * FROM tbL_name WHERE cust_sex='male';
比较运算符
运算符 | 说明 |
---|---|
= |
等于 |
<> |
不等于 |
!= |
不等于 |
< |
小于 |
<= |
小于等于 |
> |
大于 |
>= |
大于等于 |
<=> |
等于,不会返回 UNKNUOWN
|
=
与<=>
的区别:前者在左右两边有值为NULL
时会返回UNKNUOWN
,但后者不会。
判断范围查询
使用 BETWEEN
关键字。包含 起始值和结束值。
-- 伪代码:
-- SELECT * FROM 表名
-- WHERE 列 [NOT] BETWEEN 起始值 AND 结束值
SELECT * FROM tbl_sorce
WHERE sorce BETWEEN 60 AND 100;
使用 IN
关键字,可以指定一个值的枚举表。该表中会列出所有可能的值。
-- 伪代码:
-- SELECT * FROM 表名
-- WHERE 列 [NOT] IN(枚举值1[, 枚举值2, ..., 枚举值3])
SELECT * FROM tbl_sorce
WHERE sorce IN(80, 90, 100);
判断空值
使用 IS [NOT] NULL
判断空值情况。
-- 伪代码:
-- SELECT * FROM 表名
-- WHERE 列 IS [NOT] NULL
SELECT * FROM tbl_name
WHERE cust_name IS NULL;
子查询
子查询的 分类:
- 表子查询;
- 行子查询;
- 列子查询;
- 标量子查询;
结合 IN
使用的子查询:
-- 伪代码:
-- SELECT 列 FROM 表
-- WHERE 主键 IN(SELECT 外键 FROM 表 WHERE 条件)
SELECT student_name FROM tbl_student
WHERE student_no
IN(SELECT student_no FROM tbl_sorce WHERE sorce >= 60);
结合 比较运算符 使用的子查询:
-- 伪代码:
-- SELECT 列 FROM 表
-- WHERE 列 比较运算符 {ALL | ANY | SOME}(SELECT 外键 FROM 表 WHERE 条件)
SELECT student_name FROM tbl_student
WHERE student_age > SOME(SELECT teacher_age FROM tbl_teacher);
结合 EXISTS
使用的子查询:
-- 伪代码:
-- SELECT 列 FROM 表
-- WHERE [NOT] EXISTS (SELECT 外 FROM 表 WHERE 条件)
SELECT student_name FROM tbl_student
WHERE EXISTS(SELECT teacher_address FROM tbl_teacher WHERE tbl_student.student_address=tbl_teacher.teacher_address);
分组查询
使用 GROUP BY
子句进行分组查询。
使用 WITH ROLLUP
子句可以将结果集进行汇总。
-- 伪代码:
-- SELECT 列 聚合函数
-- FROM 表
-- GROUP BY 列
-- [WITH ROLLUP]
-- 在数据库 mysql_test 的表 customers 中获取一个数据结果集,
-- 要求该结果集中分别包含每个相同地址的
-- 男性客户人数和女性客户人数、
-- 总人数、客户的总人数
SELECT cust_address, cust_sex, COUNT(*) AS count_num
FROM mysql_test.customers
GROUP BY cust_address, cust_sex
WITH ROLLUP;
注意点:GROUP BY
后面跟着的列,需要与 SELECT
保持一致。(mysql 5.3 版本之后不要求)
这里的列 不包含 聚合函数列
条件查询(过滤分组)
使用 HAVING
子句,进行(分组)条件查询。
HAVING
子句与 WHERE
子句的区别:
- 过滤分组;
- 可以包含聚合函数;
- 在数据分组
GROUP BY
后进行过滤;
-- 伪代码:
-- SELECT 列 聚合函数
-- FROM 表
-- GROUP BY 列
-- HAVING 条件(可包含聚合函数)
-- 在数据库 mysql_test 的表 customers 中查找一类客户信息:
-- 要求在返回的结果集中,
-- 列出相同客户地点中满足客户人数少于3的所有客户姓名及其对应地址
-- 考试版:
SELECT cust_name, cust_address
FROM mysql_test.customers
GROUP BY cust_name, cust_address
HAVING COUNT(*) < 3;
-- 实操版:
SELECT cust_name, cust_address
FROM mysql_test.customers
GROUP BY cust_address
HAVING COUNT(*) < 3;
排序语句
使用 ORDER BY
子句进行排序。
-- 伪代码:
-- ORDER BY 列1 [ASC | DESC][, ..., 列n [ASC | DESC]]
SELECT cust_name, cust_sex
FROM customers
ORDER BY cust_name DESC, cust_address DESC;
ORDER BY
与 GROUP BY
的 差别:
ORDER BY |
GROUP BY |
---|---|
排序产生的输出 | 分组行,但输出可能不是分组的排序 |
任意列都可以使用 | 只可能使用选择列或表达式列 |
不一定需要 | 若与聚合函数一起使用列或表达式,则必须使用 |
截取语句
使用 LIMIT
子句限制被 SELECT
语句返回的行数。
-- 伪代码:
-- LIMIT 开始索引, 截取数量
-- 第二种写法:
-- LIMIT 截取数量 OFFSET 开始索引
SELECT cust_id, cust_name
FROM customers
ORDER BY cust_id
LIMIT 4,3;
视图
什么是视图
视图是数据库中的一个对象,它是数据库管理系统提供给用户的以多种角度观察数据库中数据的一种重要机制。
视图不是数据库中真是的表,而是一张 虚拟表,其自身并不存储数据。
外模式 对应到数据库中的概念就是视图。
使用视图的优点
- 集中分散数据;
- 简化查询语句;
- 重用 SQL 语句;
- 保护数据安全;
- 共享所需数据;
- 更改数据格式;
创建视图
使用 CREATE VIEW
语句,创建视图。
使用 WITH CHECK OPTION
子句,可对视图的操作进行限制。
-- 伪代码:
-- CREATE VIEW 视图
-- AS SELECT查询语句
-- [WITH CHECK OPTION]
CREATE VIEW customers_male_view
AS
SELECT *
FROM customers
WHERE cust_sex = 'male'
WITH CHECK OPTION;
删除视图
使用 DROP VIEW
语句,删除视图。
-- 伪代码:
-- DROP VIEW [IF EXISTS] 视图[, ..., 视图n]
DROP VIEW IF EXISTS customers_male_view, customers_female_view;
修改视图
使用 ALTER VIEW
语句,对已有视图的定义(结构)进行修改。
-- 伪代码:
-- ALTER VIEW 视图
-- AS SELECT查询语句
-- [WITH CHECK OPTION]
ALTER VIEW customers_male_view
AS
SELECT *
FROM customers
WHERE cust_sex = 'male' AND cust_age > 18
WITH CHECK OPTION;
查看视图
使用 SHOW CREATE VIEW
语句,查看已有视图的定义。
-- 伪代码:
-- SHOW CREATE VIEW 视图
SHOW CREATE VIEW customers_male_view;
更新视图数据
使用 INSERT
语句,通过视图向基本表 插入 数据。
-- 伪代码:
-- INSERT INTO 视图
-- VALUES(值, ..., 值n)[, ..., (值, ..., 值n)]
INSERT INTO customers_male_view
VALUES('li.li.li', 18, 'male');
使用 UPDATE
语句,通过视图向基本表 修改 数据。
-- 伪代码:
-- UPDATE 视图
-- SET 列=值[, ..., 列n=值n]
UPDATE customers_male_view
SET cust_address='china';
WHERE cust_name='li.li.li';
使用 DELETE
语句,通过视图向基本表 删除 数据。
-- 伪代码:
-- DELETE FROM 视图
DELETE FROM customers_male_view
WHERE cust_name='li.li.li';
查询视图数据
使用 SELECT
语句, 查询 视图的数据。
-- 伪代码:
-- SELECT {* | 列} FROM 视图
SELECT *
FROM customers_male_view
WHERE cust_name='chen.chen.chen';