MySQL 数据查询语言Data Query Language

MySQL基础知识

基础概念

主键需要满足的条件

1.任意两行都不具有相同的主键值
2.每一行都必须具有一个主键值且不能为NULL
3.主键列中的值不允许修改或更新
4.主键不能重用,如果某行从表中删除,它的主键也不能赋给以后的新行。

DB、DBMS、SQL

DB(database)数据库:存储数据的’仓库’,保存了一系列有组织的数据
DBMS(Database Management System)数据库管理系统:用于创建或管理DB
SQL(Structure Query Language):结构化查询语言,专门用来与数据库通信的语言

SQL特性

  1. 多条SQL必须以分号结尾,多数DBMS不需要在单条SQL语句后面加分号,但有些单条SQL语句后必须加,所以建议都加上。
  2. 处理SQL语句时,其中所有空格都会被忽略。
  • MySQL 在 Windows 环境下是大小写不敏感的
  • MySQL 在 Linux 环境下是大小写敏感的
    • 数据库名、表名、表的别名、变量名是严格区分大小写的
    • 关键字、函数名、列名(或字段名)、列的别名(字段的别名) 是忽略大小写的。
  • 推荐采用统一的书写规范:
    • 数据库名、表名、表别名、字段名、字段别名等都小写
    • SQL 关键字、函数名、绑定变量等都大写

SQL分类

  • DDL(Data Definition Languages、数据定义语言这些语句定义了不同的数据库、表、视图、索引等数据库对象,还可以用来创建、删除、修改数据库和数据表的结构。
    • 主要的语句关键字包括CREATEDROPALTER等。
  • DML(Data Manipulation Language、数据操作语言),用于添加、删除、更新和查询数据库记录,并检查数据完整性。
    • 主要的语句关键字包括INSERTDELETEUPDATESELECT等。
    • SELECT是SQL语言的基础,最为重要。
  • DCL(Data Control Language、数据控制语言),用于定义数据库、表、字段、用户的访问权限和安全级别。
    • 主要的语句关键字包括GRANTREVOKECOMMITROLLBACKSAVEPOINT等。

因为查询语句使用的非常的频繁,所以很多人把查询语句单拎出来一类:DQL(数据查询语言)。
还有单独将COMMITROLLBACK 取出来称为TCL (Transaction Control Language,事务控制语言)。

注释

单行注释:#注释文字(MySQL特有的方式)
单行注释:-- 注释文字(--后面必须包含一个空格。)
多行注释:/* 注释文字  */

DQL数据查询语言(Data Query Language)

基础查询

语法:SELECT 查询列1,查询列2.. FROM 表名;

输出所有列:SELECT * FROM 表名;

# 基础查询 
USE myemployees;
# 1.查询表中的单个字段
SELECT last_name FROM employees;

# 2.查询表中的多个字段
SELECT last_name,salary,email FROM employees;

# 3.查询表中的所有字段
# 方式一:使用*输出的顺序和原始表的顺序一样
SELECT * FROM employees;

# 方式二:可以自定义顺序
SELECT 
  `first_name`,
  `last_name`,
  `email`,
  `phone_number`,
  `manager_id`,
  `salary`,
  `job_id`,
  `department_id`,
  `hiredate`,
  `commission_pct`
FROM
   employees;
类型关键字案例说明
去重DISTINCTSELECT DISTINCT department_id FROM employees;DISTINCT 需要放到所有列名的前面,不支持部分去重,对后面所有列名的组合进行去重
重命名一个列AS 别名SELECT a AS b FROM user_profile如果别名中包含空格或特殊的字符并区分大小写时,可以加双引号,
AS可以省略但不建议
输出的是别名
着重号用``框起来SELECT * FROM ORDER;我们需要保证表中的字段、表名等没有和保留字、数据库系统或常用方法冲突。如果真的相同,使用着重号框起来。

说明
1.mysql中,单引号和双引号都可以表示字符串,没有区别
2.mysql的别名可以不加引号,如果加引号防止有空格等识别不出来,单引号和双引号以及反引号都可以
3.mysql的字段名、表名通常不需要加任何引号,如果非要加上引号,必须加反引号

查询常数

SELECT 查询还可以对常数进行查询。就是在 SELECT 查询结果中增加一列固定的常数列。这列的取值是我们指定的,而不是从数据表中动态取出的。

为什么我们还要对常数进行查询呢?

一般来说我们只从一个表中查询数据,通常不需要增加一个固定的常数列,但如果我们想整合不同的数据源,用常数列作为这个表的标记,就需要查询常数。

比如说,我们想对 USER 数据表中的员工姓名进行查询,同时增加一列字段 corporation ,这个字段固定值为"TX"

SELECT 'TX' AS corporation, NAME
FROM USER;

image

拼接函数concat/为空设置默认值函数 IFNULL

concat(参数1,参数2…) 拼接参数列表
IFNULL(表达式,默认值) 判断是否为NULL,如果为NULL使用默认值

# 查询员工名和姓连接成一个字段,并显示为姓名
SELECT CONCAT(last_name,first_name) AS 姓名 FROM employees;
SELECT  CONCAT(last_name,",",first_name,",",IFNULL(commission_pct,0)) AS out_put FROM employees;

条件查询 WHERE子句

SELECT 字段1,字段2 FROM 表名 WHERE 过滤条件

WHERE子句紧跟FROM子句

分类
1.按条件表达式筛选(> < = !=/<> >= <=)
2.按逻辑表达式筛选(&&/and ||/or !/not)
3.模糊查询(like, between and, in, is null)

比较运算符

1.比较运算符用来对表达式左边的操作数和右边的操作数进行比较,比较的结果为真则返回1,比较的结果为假则返回0,其他情况则返回NULL
2.所有运算符或列值遇到null值,运算的结果都为null,在 MySQL 里面, 空值不等于空字符串。一个空字符串的长度是 0,而一个空值的长度是空。而且,在 MySQL 里面,空值是占用空间的。

操作符说明NULL值
=1.字符串比较每个字符的ANSI编码是否相等
2.如果等号两边的值一个是整数,另一个是字符串,则MySQL会将字符串转化为数字进行比较。
不能判断NULL,意思是有NULL结果就为NULL
<=>安全等于,对NULL值处理不一样,其他返回结果与等于运算符相同可以判断NULL和其他值,结果为0。如果两边都是NULL,结果为1
<>/!=不等于不能判断NULL
</<=小于与大于等于不能判断NULL
>/>=大于与大于等于不能判断NULL

逻辑运算符

运算符作用
NOT 或 !逻辑非 否定跟着它后面的条件
AND 或 &&逻辑与
OR 或
XOR逻辑异或(偶数个1)

image

IS NULL为空运算符/IS NOT NULL不为空运算符

是否可以判断NULL

类型普通类型的数值null型
赋值 =/!=×
关键字 is×
安全等于 <=>
IS NULLISNULL(参数)
IS关键字,判断是否为NULLISNULL(参数) 是一个函数,判断参数是否为空,返回函数结果1真0假
IS NOT NULL,判断不为空NOT ISNULL(参数),意思是对ISNULL的
# 模糊查询
# 判断为空
SELECT last_name ,commission_pct FROM employees WHERE commission_pct IS NULL ;
SELECT employee_id,commission_pct FROM employees WHERE ISNULL(commission_pct);

# 判断不为空
SELECT employee_id,commission_pct FROMemployees WHERE NOT ISNULL(commission_pct);
SELECT employee_id,commission_pct FROMemployees WHERE commission_pct IS NOT NULL;
BETWEEN AND 两值之间运算符

betwenn相当于>= and相当于<=

注意事项
1.包含临界值
2.顺序不能乱

# 查询员工编号在100到120之间的员工信息
SELECT * FROM employees WHERE employee_id BETWEEN 100 AND 120;
IN属于运算符/NOT IN不属于运算符
mysql> SELECT 'a' IN ('a','b','c'), 1 IN (2,3), NULL IN ('a','b'), 'a' IN ('a', NULL);
+----------------------+------------+-------------------+--------------------+
| 'a' IN ('a','b','c') | 1 IN (2,3) | NULL IN ('a','b') | 'a' IN ('a', NULL) |
+----------------------+------------+-------------------+--------------------+
| 1 | 0 | NULL | 1 |
+----------------------+------------+-------------------+--------------------+

IN 和 OR实现的相同功能

  1. IN的执行速度比OR快
  2. IN 后面可以跟SELECT子句
WHERE manager_id IN (100, 101);
WHERE manager_id=100 OR managerid_id=101;
like 模糊匹配运算符

语法: like 搜索模式
搜索模式:由字面值、通配符或两者组合构成的搜索条件

说明
1.一般和通配符搭配使用,
2.

通配符说明
%代表零个或多个字符
不可以匹配NULL
_任意单个字符

3.ESCAPE关键字 自定义转移符
4.可以判断数值型和字符型,都写在引号里

通配符的使用注意
1.通配符搜索的处理比较慢,其他操作符能够达到相同的效果,尽量使用其他操作符
2.尽量不要放在搜索模式的开头处,搜索起来最慢

# 模糊查询
# 1.查询员工名中包含字符a(模糊条件)的员工信息
SELECT * FROM employees WHERE last_name LIKE '%a%';

# 2.查询员工名中第三个字符为e,第五个字符为a的员工名和工资
SELECT last_name,salary 
FROM employees
WHERE	last_name LIKE '__e_a%';

# 3.查询员工名中第二个字符为_的员工名 
# 方法一:\转义字符
# 方法二:ESCAPE关键字 自定义转移符
SELECT last_name
FROM employees
# where last_name LIKE '_\_%'、
WHERE last_name LIKE '_S_%' ESCAPE 'S';
REGEXP 正则运算符

REGEXP运算符用来匹配字符串,语法格式为: expr REGEXP [BINARY] ‘匹配条件’
BINARY:MySQL中的正则表达式匹配不区分大小写,该关键字的意思是区别大小写

正则表达式的使用

多数正则表达式实现使用单个反斜杠转义特殊字符,但MySQL需要两个反斜杠,MySQL自己解释一个,正则表达式库解释另一个

聚集函数

Mysql的聚合函数不支持嵌套使用
聚集函数:对一组数据进行汇总,输入的是一组数据的集合,输出的是单个值。

语法:selsect 函数名([DISTINCT] 参数) [from 表]
1.函数中的参数使用到了表中属性时需要添加form表
2.DISTINCT 可选,表示对参数去重,把不同的参数作为输入。只能作用于参数指定了列名的函数,COUNT(DISTINCT *)不可以使用。

使用案例

  • 确定表中的总行数、符合条件的行数
  • 获取表中行组的和
  • 找出最大值、最小值、平均值
函数说明作用范围是否忽略NULL
AVG()返回某列的平均值对数值型数据使用
SUM()返回之和对数值型数据使用
MAX()返回最大值对任意数据类型使用,如果是文本数据,返回最后面的
MIN()返回最小值对任意数据类型使用,如果是文本数据,返回最前面的
COUNT()COUNT(*)返回表中记录总数,
COUNT(column)对特定的列中具有值得行进行计数
COUNT(1或者其他常数值)相当于多了列,一列全部是常数值
对任意数据类型使用COUNT(*) ×
COUNT(column) √
COUNT(1或者其他常数值) √
问题:用count(*),count(1),count(列名)谁好呢?

其实,对于MyISAM引擎的表是没有区别的。这种引擎内部有一计数器在维护着行数。
Innodb引擎的表用count(*),count(1)直接读行数,复杂度是O (n),因为innodb真的要去数一遍。COUNT(*) = COUNT(1)>COUNT(列名)。

分组GROUP BY 和 HAVING

语法
SElECT 分组之后执行的函数[,列]
FROM table
[where condition]
[group by group_by_expression]
[order by 子句];

注意:

1.group by 的位置必须在where子句之后,order by 子句之前。
2.这里的列如果有,只能是在分组条件中出现的列,否则分组之后的行数,和这里写的列选出来的行数不一样。

单个列分组

案例:查询每个工种的最高工资 (分组条件每个工种)

SELECT MAX(salary)[,job_id] # 为了方法查看最高工资是哪个job_id可以写出来
FROM employees
GROUP BY job_id;
多个列分组

案例:查询每个部门(不为null)每个工种的员工的平均工资,并按平均工资的高低显示 (分组条件部门和工种)

多个字段之间用逗号隔开并没有顺序要求

SELECT AVG(salary) 平均工资[,department_id,job_id] # 基于可读性加上了
FROM employees
WHERE department_id IS NOT NULL
GROUP BY department_id,job_id
ORDER BY 平均工资 DESC;

SELECT 中出现的非组函数的字段必须声明在GROUP BY 中

# 按department_id分组,一个部门占一行数据
# 这个一个部门里面有好几种job_id,那么应该选哪一个呢???
# 这个是错误写法
SELECT AVG(salary) 平均工资,department_id,job_id
FROM employees
WHERE department_id IS NOT NULL
GROUP BY department_id;
WITH ROLLUP

作用:在所有查询出的分组记录之后,添加一条记录,该记录把分组之后的记录当作输入再执行一次聚合函数

SELECT MAX(salary),job_id
FROM employees
GROUP BY job_id WITH ROLLUP;

# job_id MAX(salary)
# ...
# NULL  把结果MAX(salary)列看成一组,找出其中最高的
# 如果是avg函数,相当于所有的平均值再求一次平局
分组过滤 HAVING

案例1:查询各个部分中最高工资比10000高的部门信息

# 错误写法
SELECT MAX(salary) ,department_id
FROM employees
WHERE MAX(salary)>10000;
GROUP BY department_id;

为什么错误?
WHERE比分组先执行

HAVING注意点
1.如果过滤条件中使用了聚合函数,必须使用HAVING
2.HAVING 必须声明在GROUP BY后面
3.开发中,使用HAVING的前提是GROUP BY使用。(可单独使用但是不推荐)

# 正确写法
SELECT MAX(salary) ,department_id
FROM employees
GROUP BY department_id;
HAVING MAX(salary)>10000;

案例2:查询部门id为10,20这2个部门中最高工资比10000高的部分信息。

# 方式1 推荐:执行效率更高
SELECT MAX(salary) ,department_id
FROM employees
WHERE department_id IN (10,20)
GROUP BY department_id;
HAVING MAX(salary)>10000;

# 方式2
SELECT MAX(salary) ,department_id
FROM employees
GROUP BY department_id;
HAVING MAX(salary)>10000 AND  department_id IN (10,20);

方式1在执行基础查询的时候只选出了department_id为10或20的数据进行分组。先筛选再分组
方式2在查询出了所有department_id的数据,最后选出了department_id为10或20的数据。先分组再筛选

WHERE与HAVING的对比
-|优点|缺点
WHERE|先筛选再关联,执行效率高|不能使用分组中的计算函数作为过滤条件,WHERE没有分组的概念
HAVING|可以使用分组中的计算函数为条件|先分组再筛选,执行效率低

排序 ORDER BY子句

使用 ORDER BY 子句排序
语法:ORDER BY xxx[ASC/DESC],yyy [ASC/DESC] ;
ASC(ascend): 升序,默认
DESC(descend):降序

知识点:
1.支持多个字段排序,先按第一个排,第一个相同按第二个排
2.order by 子句一般放在查询语句最后。limit子句除外

LIMIT

限制返回条数
语法
LIMIT x,y x默认0(可省略),返回从x开始的y条数据
LIMIT x OFFSET y 从x开始取y行

说明:
LIMIT 子句必须放在整个SELECT语句的最后

案例:分页显示公式

# PageNo是当前页数,PageSize是每页的大小
LIMIT(PageNo - 1)\*PageSize,PageSize;
案例:与LIMIT结合,找最大/小
# 找到最贵的
SELECT prod_price
FROM products
ORDER BY prod_price DESC
LIMIT 1;

多表查询

通常使用sql99标准

等值与非等值:
等值连接:连接条件 等号
非等值连接:连接条件 不是等号

自连接与非自连接:
自连接:多表是指自己与自己
使用场景:同一张表需要查询两遍

内连接与非内连接
内连接:只取交集

注意点:

1.给表起了别名之后,原名就被覆盖了,之后使用都使用别名。
2.建议:从sql优化的角度,建议多表查询时,每个字段前都指明所在的表

UNION 合并查询

把多条SELECT语句的结果组合成单个结果集。
每个表对应的列数和数据类型必须相同,并对应。

语法:
SELECT … FROM t1
UNION [ALL]
SELECT … FROM t2

  • UNION: A ∪ B 会自动去重
  • UNION ALL: A ∪ B 不会去重,显示所有

执行UNION ALL语句时所需要的资源比UNION语句少。如果明确知道合并数据后的结果数据不存在重复数据,或者不需要去除重复的数据,则尽量使用UNION ALL语句,以提高数据查询的效率。

/*
案例:查看学校为山东大学或者性别为男性的用户的device_id、gender、age和gpa数据,请取出相应结果,结果不去重。
*/
SELECT device_id,gender,age,gpa
FROM user_profile
WHERE university = "山东大学" OR gender="male"; # 默认去重,一行又是male又是山东大学只会被匹配一次

# 不去重写法
SELECT device_id,gender,age,gpa
FROM user_profile
WHERE university = "山东大学" # 一行又是male又是山东大学这里匹配一次
UNION ALL
SELECT device_id,gender,age,gpa
FROM user_profile
WHERE gender = "male"; # 一行又是male又是山东大学这里又匹配一次
sql92语法

等值连接

说明:where后面添加连接条件

笛卡尔积:A表每一行都和B表的所有行匹配过

/*
sql92内连接写法如下,mysql不支持sql92外连接写法
案例1:查询员工名、工种号、工种名
*/
SELECT last_name,e.`job_id`,job_title
FROM employees e,jobs j
WHERE e.`job_id` = j.`job_id`;

# 有筛选条件使用and
/*
案例2.查询有奖金的员工名,部门名
*/
SELECT last_name,department_name
FROM employees e,departments d
WHERE e.`department_id` = d.`department_id`
AND commission_pct IS NOT NULL;

自连接和非自连接

自连接:多表是指自己与自己
使用场景:同一张表需要查询两遍

/*
案例1:查询员工名和上级的名称  同一张表需要寻找两遍
第一遍找员工的领导编号是是多少,第二遍找这个编号对应的人是谁
*/
SELECT 
  e.employee_id 员工编号,
  e.last_name 员工名,
  m.employee_id 领导编号,
  m.last_name 领导名
FROM
  employees e,employees m
WHERE m.employee_id =e.manager_id;
SQL99标准
  • 内连接:用第一张的表的一行去匹配第二张表的每一行,匹配成功则留下来 --只取交集A∩B
  • 外连接 一般题目有:所有
    • 左外连接,除了交集还多包含了左表中不匹配的行 --AU(A∩B),左表为主表
    • 右外连接,除了交集还多包含了右表中不匹配的行 --(A∩B)UB,右表为主表
    • 全连接,AUB

sql99标准

select 查询列表
from 表1 别名
[连接类型] join 表2 别名
on 连接条件

连接类型含义案例
内连接AuBFROM A [inner] JOIN B ON
左外连接AU(A∩B)FROM A LEFT JOIN B ON
右外连接(A∩B)UBFROM A RIGHt JOIN B ON
全连接AUBFROM A FULL JOIN B ON(mysql不支持)

image

SQL99新特性1-自然连接NATURAL JOIN

自动查询两张表中所有相同字段,不用指出来,然后进行等值连接

# SQL92标准中
SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
ON e.`department_id` = d.`department_id`
AND e.`manager_id` = d.`manager_id`;

# SQL99中
SELECT employee_id,last_name,department_name
FROM employees e NATURAL JOIN departments d;
SQL99新特性2-USING连接

USING() 在一下情况可以代替 ON

SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
ON e.department_id = d.department_id; //语句1

SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
USING (department_id) # 当字段名一样的时候,可以用这句替换语句1

子查询

子查询的基本使用
  • 子查询(内查询)在主查询之前一次执行完成。
  • 子查询的结果被主查询(外查询)使用 。

注意事项

  • 子查询要包含在括号内
  • 将子查询放在比较条件的右侧
  • 单行操作符对应单行子查询,多行操作符对应多行子查询

子查询的分类

从子查询返回的结果的条目数

  • 单行子查询,子查询值返回一行
  • 多行子查询,子查询值返回多行

从内查询是否被执行多次

  • 相关子查询:案例查询工资大于本部门平均工资的员工信息,子查询结果随着员工的部门改变。
  • 不相关子查询:子查询的结果固定?和主查询没有相关性

子查询的位置
除了GROUP BY和LIMIT之外都可以使用

单行子查询
操作符含义
=equal to
>greater than
>=greater than or equal to
<less than
<=less than or equal to
<>not equal to

子查询编写技巧:①从里往外写 ②从外往里写

案例1:查询与141号或174号员工的manager_id和department_id相同的其他员工的employee_id,
manager_id,department_id

# 不成对比较
SELECT employee_id, manager_id, department_id
FROM employees
WHERE manager_id IN
  (SELECT manager_id
  FROM employees
  WHERE employee_id IN (174,141))
AND department_id IN
   (SELECT department_id
    FROM employees
    WHERE employee_id IN (174,141))
AND employee_id NOT IN(174,141);

# 成对比较,了解
SELECT employee_id, manager_id, department_id
FROM employees
WHERE (manager_id, department_id) IN
    (SELECT manager_id, department_id
     FROM employees
    WHERE employee_id IN (141,174))  
AND employee_id NOT IN (141,174);
多行子查询
操作符含义
IN等于列表中的任意一个
ANY需要和单行比较操作符一起使用,和子查询返回的某一个值比较成功
ALL需要和单行比较操作符一起使用,和子查询返回的所有值比较成功
SOME实际上是ANY的别名,作用相同,一般常使用ANY

案例1:查询最低的平均工资

# MySQL中的聚合函数是不能嵌套使用
SELECT MIN(sav_sal)
FROM(
  SELECT AVG(salary) avg_sal
  FROM employees
  GROUP BY depatment_id
) t # 必须给表起别名,不然是个无名表

# 方式2
SELECT AVG(salary) avg_sal
FROM employees
GROUP BY depatment_id
ORDER BY avg_sal
LIMIT 1;
相关子查询

如果子查询的执行依赖于外部查询,通常情况下都是因为子查询中的表用到了外部的表,并进行了条件
关联,因此每执行一次外部查询,子查询都要重新计算一次,这样的子查询就称之为 关联子查询 。
相关子查询按照一行接一行的顺序执行,主查询的每一行都送给子查询并执行一次子查询。

子查询中使用主查询中的列
案例1:查询员工中工资大于本部门平均工资的员工的last_name,salary和其department_id


uploading-image-506667.png

** EXISTS 与 NOT EXISTS关键字**

  • 关联子查询通常也会和 EXISTS操作符一起来使用,用来检查在子查询中是否存在满足条件的行。
  • 如果在子查询中不存在满足条件的行
    • 条件返回 FALSE
    • 继续在子查询中查找
  • 如果在子查询中存在满足条件的行:
    • 不在子查询中继续查找
    • 条件返回 TRUE

题目中可以使用子查询,也可以使用自连接。一般情况建议你使用自连接,因为在许多 DBMS 的处理过
程中,对于自连接的处理速度要比子查询快得多。
可以这样理解:子查询实际上是通过未知表进行查询后的条件判断,而自连接是通过已知的自身数据表
进行条件判断,因此在大部分 DBMS 中都对自连接处理进行了优化。

执行顺序

SELECT子句的顺序
子句说明是否必须使用
SElECT
FROM仅在表中选择数据时使用
where行级过滤
必须紧跟FROM
×
group by必须在order by与where之间仅在按组计算聚集时使用
HAVING组级过滤
HAVING必须紧跟GROUP BY
×
order by一般放最后面,有LIMIT就倒数第二×
Limit必须放在最后×
# sql92语法
SELECT ...,....,...
FROM ...,...,....
WHERE 多表的连接条件
AND 不包含组函数的过滤条件
GROUP BY ...,...
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...

# sql99语法
SELECT ...,....,...
FROM ... JOIN ...
ON 多表的连接条件
JOIN ...
ON ...
WHERE 不包含组函数的过滤条件
AND/OR 不包含组函数的过滤条件
GROUP BY ...,...
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...
执行顺序
  1. FROM—> ON 多表的连接条件,可以过滤部分数据 —(LEFT/RIGHT JOIN)
  2. WHERE (不可以使用别名)
  3. GROUP BY
  4. HAVING (可以使用别名)
  5. SELECT 的字段
  6. DISTINCT
  7. ORDER BY
  8. LIMIT

注意:SQL对查询做了增强没有严格遵循SQL的执行顺序,where后面不能用select中的别名,但是group by ,order by都是可以的racle数据库严格遵循了SQL执行顺序在Oracle里group by是不能引用select里的别名的

单行函数

对一行进行变换,每行返回一个结果

流程控制语句
函数用法
IF(value,value1,value2)如果value的值为TRUE,返回value1,否则返回value2
CASE WHEN 条件1 THEN 结果1 WHEN 条件2 THEN 结果2… ELSE END相当于Java的if…else if…else…
CASE expr WHEN 常量值1 THEN 值1 WHEN 常量值1 THEN值1 … ELSE 值n END相当于Java的switch…case…
SELECT IF(age>=25,'25岁及以上','25岁以下') AS age_cut,count(*)
FROM user_profile
group by age_cut;

/*
25岁及以上|4
25岁以下|3
*/

SELECT device_id, gender,CASE 
WHEN age IS NULL THEN '其他' 
WHEN age>=25 THEN '25岁及以上'
WHEN age>=20 THEN'20-24岁'
ELSE '20岁以下'
END  AS age_cut 
FROM user_profile
GROUP BY age_cut,gender,device_id

/*
2138|male|20-24岁
3214|male|其他
6543|female|20-24岁
2315|female|20-24岁
5432|male|25岁及以上
2131|male|25岁及以上
4321|male|25岁及以上
*/

SELECT CASE 1
WHEN 1 THEN '我是1'
WHEN 2 THEN '我是2'
ELSE '你是谁
日期函数
文本函数

MySQL中字符串的位置从1开始

函数说明
LTRIM(s)去掉字符串s左侧的空格
RTRIM(s)去掉字符串s右侧的空格
TRIM(s)去掉字符串s开始与结尾的空格
TRIM(s1 FROM s)去掉字符串s开始与结尾的s1
TRIM(LEADING s1 FROM s)去掉字符串s开始处的s1
TRIM(TRAILING s1FROM s)去掉字符串s结尾处的s1
REPEAT(str, n)返回str重复n次的结果
SUBSTRING_INDEX(str,delim,count)str:要处理的字符串,delim:分隔符,count:计数。
如果count是正数,那么就是从左往右数,第N个分隔符的左边的所有内容,如果count是负数,那么就是从右往左数,第N个分隔符的右边的所有内容
SUBSTRING(str,n ,m)返回字符串str从第n个字符截取到第m个字符;

案例1:从180cm,75kg,25,male中提取出年龄25

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(profile,',',-2),',',1) AS age # 先截取出25,male再截取出25
数学函数
函数说明
ROUND(x)四舍五入,相当与ROUND(X,0)
ROUND(x,y)四舍五入,并保留到小数点后面Y位
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值