Luo Hao

MySQL——问题小书

Rehoni / 2023-10-12


问题1、截取字符串

具体描述

left

开始截取字符串

用法:left(str, length),即:left(被截取字符串, 截取长度)

subString
substring_index

https://yuanrengu.com/2020/9cfe2ad6.html

问题2、查看相关信息

# 查看端口
show variables like 'port';
# 查看表结构
desc tablename;
# 查看mysql版本
select version() from dual;
# 查看mysql时区
show variables like '%time_zone';

system_time_zone    CST
time_zone    +08:00

set global time_zone = '+08:00';
flush privileges;
# 全局时区和当前session时区
select @@global.time_zone, @@session.time_zone;
# 获取当前时间戳,各个类型
SELECT TIME_TO_SEC(NOW()),
       NOW(),
       current_timestamp(),
       REPLACE(unix_timestamp(NOW(3)), '.', ''),
       REPLACE(unix_timestamp(current_timestamp(3)), '.', ''),
       current_timestamp(3),
       unix_timestamp(current_timestamp(3));
# 审计日志相关
show variables like 'init_connect';
show variables like '%log_bin%';# 查看是否开启binlog
show variables like '%binlog%'; # 查看binlog相关参数
show variables like '%audit%';
set global init_connect=NULL;
show binlog events;# 只查看第一个binlog文件的内容
show binlog events in 'mysql-bin.000002'; # 查看指定binlog文件的内容
show master status;# 查看当前正在写入的binlog文件
show binary logs;# 获取binlog文件列表

问题3、用户操作

drop user 'rehoni'@'%'; # 删除用户
select Host,user from mysql.user; # 查看用户
create user 'rehoni'@'%' identified by 'rehoni'; # 创建用户
ALTER USER dbadmin@localhost IDENTIFIED BY 'newpasswd3'; # 修改用户密码
update user set host='%' where mysql.user = 'his'; #开通远程访问权限
show grants for 'rehoni'@'%'; # 查看权限
grant all privileges on *.* to 'rehoni'@'%';# 赋予权限
flush privileges ; # 刷新权限
show grants for 'root'@'%';# 查看权限

问题4、增加表的字段

alter table imp_transform_ocg
    add vc varchar(64) null comment 'c2h4/c2h6气体比值';

问题5、修改创建视图

drop view imp_transform_ocg_latest;
create view imp_transform_ocg_latest as
select a.*
from imp_transform_ocg a,
     (
         select uri, max(ACQTM) acqtm
         from imp_transform_ocg
         group by uri) b
where a.URI = b.URI
  and a.ACQTM = b.acqtm
order by a.URI;

问题6、从表创建表

问题描述

从已有的表的数据创建一张新的表的数据

解决方案和原理

drop table operate_user;
create table
    operate_user
as
select NAME as username, '1' as priority, now() as control_time
from nrcloud.users;

问题7、日期加减

问题描述

日期做加减法

解决方案和原理

select max(priority)
from operate_user
where control_time between
# 注意这里的data_sub和interval的用法
    date_sub(now(), interval '599999999' minute) and now()

问题8、空值排序

问题描述

表里该字段大部分为空,需要非空值排在前列

解决方案和原理

-- 按空值排序
select FETIME, CLOSE_VAL, ROBOT_SCHEME, VIDEO_SCHEME
from ems_status e
order by
       # 1、传入这个条件,则此两个字段均为空的排在后边
       # e.ROBOT_SCHEME = '' and e.VIDEO_SCHEME = '';
       # 2、直接desc,逐个按顺序排列下去
       e.ROBOT_SCHEME desc, e.VIDEO_SCHEME desc;

-- 按长度排序
select FETIME, CLOSE_VAL, ROBOT_SCHEME, VIDEO_SCHEME, length(ROBOT_SCHEME) len
from ems_status
order by len desc;

问题9、添加行号

问题描述

返回给后端的带行号的数据

解决方案和原理

select (@i := @i + 1) as row_num, A.*
from (
        # 需要添加行号的视图
         select b.id,
                a.SIGNAL_NAME,
                a.ID as signal_id,
                b.VIDEO_SCHEME,
                b.SOUND,
                b.SOUND_TYPE,
                b.video,
                b.PICTURE,
                d.STATION_NAME
         from base_signal a
                  left join relation_signal_scheme b on b.SIGNAL_ID = a.ID
                  left join relation_id c on c.signal_id = a.ID
                  left join base_station d on d.ID = c.station_id
     ) A,
     (Select @i := 0) B;

问题10、创建视图

create view imp_transform_ocg_latest as
# as 后跟需要创建好的视图
select a.*
from imp_transform_ocg a,
     (
         select uri, max(ACQTM) acqtm
         from imp_transform_ocg
         group by uri) b
where a.URI = b.URI
  and a.ACQTM = b.acqtm
order by a.URI;

问题11、修改字段大小写和字符集

SELECT
CONCAT('ALTER table ',t2.table_schema,'.',t2.table_name,' CHANGE ',' \`',t2.column_name,'\` \`',UPPER(t2.column_name),'\` ',
t2.column_type,' ',CASE WHEN t2.is_nullable='NO' THEN 'not null' ELSE 'null' END,' COMMENT ''',t2.column_comment,''';') AS c
FROM information_schema.tables t1, information_schema.columns t2
WHERE t1.table_schema = 'sdjk'
AND t1.table_type = 'base table'
AND t1.table_schema = t2.table_schema
AND t1.table_name = t2.table_name;

show character set ;
select concat('alter table `',TABLE_NAME,'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;')
as target_tables
from information_schema.TABLES
where TABLE_SCHEMA = 'standard'
and TABLE_TYPE = 'base table';

问题12、转Oracle的问题

-- 1. to_date ==> str_to_date
str_to_date(#{startTime},'%Y-%m-%d %H:%i:%s')
-- 2. to_char ==> date_format 
date_format(acqtm,'%Y-%m-%d %H:%i:%s')
-- 3. || ==> concat
-- 4. sysdate() | sysdate

问题13、修改MySQL时区

查看mysql当前时间,当前时区

> select curtime();  #或select now()也可以
+-----------+
| curtime() |
+-----------+
| 15:18:10 |
+-----------+
> show variables like "%time_zone%";
+------------------+--------+
| Variable_name  | Value |
+------------------+--------+
| system_time_zone | CST  |
| time_zone    | SYSTEM |
+------------------+--------+
2 rows in set (0.00 sec)

time_zone说明mysql使用system的时区,system_time_zone说明system使用CST时区

方法一,直接修改

> set global time_zone = '+8:00'; ##修改mysql全局时区为北京时间,即我们所在的东8区
> set time_zone = '+8:00'; ##修改当前会话时区
> flush privileges; #立即生效

方法二:通过修改my.cnf配置文件来修改时区

# vim /etc/my.cnf ##在[mysqld]区域中加上
default-time_zone = '+8:00'
# /etc/init.d/mysqld restart ##重启mysql使新时区生效

方法三:如果不方便重启mysql,又想临时解决时区问题,可以通过php或其他语言在初始化mysql时初始化mysql时区

这里,以php为例,在mysql_connect()下使用:

mysql_query("SET time_zone = '+8:00'")

这样可以在保证你不重启的情况下改变时区。但是mysql的某些系统函数还是不能用如:now()。

问题14、mysql内置Json操作函数

MySQL 官方列出 JSON 相关的函数,完整列表如下 [doc ]:

分类 函数 描述
json 创建函数 json_array() 创建 json 数组
json_object() 创建 json 对象
json_quote() 用双引号包裹 json 文档
json 查询函数 json_contains() 判断是否包含某个 json 值
json_contains_path() 判断某个路径下是否包 json 值
json_extract() 提取 json 值
column->path json_extract() 的简洁写法,5.7.9 开始支持
column-»path json_unquote(json_extract()) 的简洁写法,5.7.13 开始支持
json_keys() 把 json 对象的顶层的全部键提取为 json 数组
json_search() 按给定字符串关键字搜索 json,返回匹配的路径
json 修改函数 json_append() 5.7.9 废弃,改名为 json_array_append
json_array_append() 在 josn 文档末尾添加数组元素
json_array_insert() 在 josn 数组中插入元素
json_insert() 插入值(只插入新值,不替换旧值)
json_merge() 5.7.22 废弃,与 json_merge_preserve() 同义
json_merge_patch() 合并 json 文档,重复键的值将被替换掉
json_merge_preserve() 合并 json 文档,保留重复键
json_remove() 删除 json 文档中的数据
json_replace() 替换值(只替换旧值,不插入新值)
json_set() 设置值(替换旧值,或插入新值)
json_unquote() 移除 json 值的双引号包裹
json 属性函数 json_depth() 返回 json 文档的最大深度
json_length() 返回 json 文档的长度
json_type() 返回 json 值的类型
json_valid() 判断是否为合法 json 文档
json 工具函数 json_pretty() 美化输出 json 文档,5.7.22 新增
json_storage_size() 返回 json 文档占用的存储空间,5.7.22 新增

官方文档对全部函数都作了充分解释并提供一定的示例代码。下文挑选了部分函数,演示它们的使用方法。

-- 创建 tbl 表,字段 data 为 json 类型
mysql> create table tbl (data JSON);
Query OK, 0 rows affected (0.17 sec)

-- 插入 json 对象
mysql> insert into tbl values ('{"id": 1, "name": "Will"}');
Query OK, 1 row affected (0.04 sec)

-- 插入 json 数组
mysql> insert into tbl values ('[1, 42, 1024]');
Query OK, 1 row affected (0.01 sec) 

-- 使用 json_object() 创建 json 对象
mysql> insert into tbl values (json_object('id', 2, 'name', 'Joe'));
Query OK, 1 row affected (0.02 sec)

-- 使用 json_array() 创建 json 数组
mysql> insert into tbl values (json_array(1, "abc", null, true, curtime()));
Query OK, 1 row affected (0.02 sec)

-- 查询 tbl 表数据
mysql> select * from tbl;
+-------------------------------------------+
| data                                      |
+-------------------------------------------+
| {"id": 1, "name": "Will"}                 |
| [1, 42, 1024]                             |
| {"id": 2, "name": "Andy"}                 |
| [1, "abc", null, true, "20:27:41.000000"] |
+-------------------------------------------+
4 rows in set (0.00 sec)

JSON_EXTRACT 查询局部数据

mysql> SELECT JSON_EXTRACT('{"name":"Zhaim","tel":"13240133388"}',"$.name");
+---------------------------------------------------------------+
| JSON_EXTRACT('{"name":"Zhaim","tel":"13240133388"}',"$.name") |
+---------------------------------------------------------------+
| "Zhaim"                                                       |
+---------------------------------------------------------------+

# 可以使用 column->path 的形式提取元素的值,对应字符串类型的 category->'$.name' 中还包含着双引号,可以用 JSON_UNQUOTE 函数将双引号去掉
# 从 MySQL 5.7.13 起也可以通过这个操作符 ->> 这个和 JSON_UNQUOTE 是等价的
# 用 -> 直接提取时要注意元素值的类型
mysql> SELECT * FROM lnmp WHERE category->>'$.name' = 'lnmp.cn';
+----+------------------------------+-----------+
| id | category                     | tags      |
+----+------------------------------+-----------+
|  1 | {"id": 1, "name": "lnmp.cn"} | [1, 2, 3] |
+----+------------------------------+-----------+

JSON_INSERT 插入新的元素

mysql> UPDATE lnmp SET category = JSON_INSERT(category, '$.name', 'lnmp', '$.url', 'www.lnmp.cn') WHERE id = 1;

mysql> SELECT * FROM lnmp;
+----+----------------------------------------------------+-----------+
| id | category                                           | tags      |
+----+----------------------------------------------------+-----------+
|  1 | {"id": 1, "url": "www.lnmp.cn", "name": "lnmp.cn"} | [1, 3, 4] |
|  2 | {"id": 2, "name": "php.net"}                       | [1, 3, 5] |
+----+----------------------------------------------------+-----------+

JSON_SET 插入或覆盖元素

mysql> UPDATE lnmp SET category = JSON_SET(category, '$.host', 'www.lnmp.cn', '$.url', 'http://www.lnmp.cn') WHERE id = 1;

mysql> SELECT * FROM lnmp;
+----+----------------------------------------------------------------------------------+-----------+
| id | category                                                                         | tags      |
+----+----------------------------------------------------------------------------------+-----------+
|  1 | {"id": 1, "url": "http://www.lnmp.cn", "host": "www.lnmp.cn", "name": "lnmp.cn"} | [1, 3, 4] |
|  2 | {"id": 2, "name": "php.net"}                                                     | [1, 3, 5] |
+----+----------------------------------------------------------------------------------+-----------+

JSON_REPLACE 替换已有元素

mysql> UPDATE lnmp SET category = JSON_REPLACE(category, '$.name', 'php', '$.url', 'http://www.php.net') WHERE id = 2;

mysql> SELECT * FROM lnmp;
+----+----------------------------------------------------------------------------------+-----------+
| id | category                                                                         | tags      |
+----+----------------------------------------------------------------------------------+-----------+
|  1 | {"id": 1, "url": "http://www.lnmp.cn", "host": "www.lnmp.cn", "name": "lnmp.cn"} | [1, 3, 4] |
|  2 | {"id": 2, "name": "php"}                                                         | [1, 3, 5] |
+----+----------------------------------------------------------------------------------+-----------+

JSON_REMOVE 删除部分元素

mysql> UPDATE lnmp SET category = JSON_REMOVE(category, '$.url', '$.host') WHERE id = 1;

mysql> SELECT * FROM lnmp;
+----+------------------------------+-----------+
| id | category                     | tags      |
+----+------------------------------+-----------+
|  1 | {"id": 1, "name": "lnmp.cn"} | [1, 3, 4] |
|  2 | {"id": 2, "name": "php"}     | [1, 3, 5] |
+----+------------------------------+-----------+

问题15、where和inner join区别

在多表查询中,一些SQL开发人员更喜欢使用WHERE来做join,比如:

SELECT a.ID, b.Name, b.Date FROM Customers a, Sales b WHERE a.ID = b.ID;

缺点:在上面语句中,实际上是创建了两张表的笛卡尔积,所有可能的组合都会被创建出来。在笛卡尔连接中,在上面的例子中,如果有1000顾客和1000条销售记录,这个查询会先产生1000000个结果,然后通过正确的 ID过滤出1000条记录。 这是一种低效利用数据库资源,数据库多做100倍的工作。 在大型数据库中,笛卡尔连接是一个大问题,对两个大表的笛卡尔积会创建数10亿或万亿的记录。

为了避免创建笛卡尔积,应该使用INNER JOIN :

SELECT a.ID, b.Name, b.Date FROM Customers a INNER JOIN Sales b ON a.ID = b.ID;

优点:如上面语句,使用inner join 这样数据库就只产生等于ID 的1000条目标结果。增加了查询效率。

有些数据库系统会识别出 WHERE连接并自动转换为 INNER JOIN。在这些数据库系统中,WHERE 连接与INNER JOIN 就没有性能差异。但是, INNER JOIN 是所有数据库都能识别的,因此DBA会建议在你的环境中使用它。

  1. INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录。
  2. LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录。
  3. RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录。

问题16、mysql日期类型和默认设置

日期类型区别及用途

MySQL 的日期类型有5个,分别是: date、time、year、datetime、timestamp。

image-20240611143605627

DATETIME

DATETIME 用于表示 年月日 时分秒,是 DATE和TIME 的组合,并且记录的年份(见上表)比较长久。如果实际应用中有这样的需求,就可以使用 DATETIME 类型。

TIMESTAMP

  TIMESTAMP 用于表示 年月日 时分秒,但是记录的年份(见上表)比较短暂。

  TIMESTAMP 和时区相关,更能反映当前时间。当插入日期时,会先转换为本地时区后再存放;当查询日期时,会将日期转换为本地时区后再显示。所以不同时区的人看到的同一时间是不一样的。

表中的第一个 TIMESTAMP 列自动设置为系统时间(CURRENT_TIMESTAMP)。当插入或更新一行,但没有明确给 TIMESTAMP 列赋值,也会自动设置为当前系统时间。如果表中有第二个 TIMESTAMP 列,则默认值设置为0000-00-00 00:00:00。

TIMESTAMP 的属性受 Mysql 版本和服务器 SQLMode 的影响较大。

如果记录的日期需要让不同时区的人使用,最好使用 TIMESTAMP。

DATE

DATE 用于表示年月日,如果实际应用值需要保存年月日就可以使用DATE。

TIME

TIME 用于表示时分秒,如果实际应用值需要保存时分秒就可以使用TIME。

YEAR

YEAR 用于表示 年份,YEAR 有2位(最好使用4位)和4位格式的年。 默认是4位。如果实际应用只保存年份,那么用1bytes 保存YEAR 类型完全可以。不但能够节约存储空间,还能提高表的操作效率。

将在“菜鸟教程”和百度获取的资料,整理成如下表格:

类型 字节 格式 用途 是否支持设置系统默认值
date 3 YYYY-MM-DD 日期值 不支持
time 3 HH:MM:SS 时间值或持续时间 不支持
year 1 YYYY 年份 不支持
datetime 8 YYYY-MM-DD HH:MM:SS 日期和时间混合值 不支持
timestamp 4 YYYYMMDD HHMMSS 混合日期和时间,可作时间戳 支持

日期类型的 default 设置

关于 default 设置,通常情况下会使用当前时间作为默认值。 Example:

ts_time timestamp NOT NULL DEFAULT NOW();
1

or

ts_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP();
1

根据上表可知,除了 timestamp 类型支持系统默认值设置,其他类型都不支持。 如果建表语句中有:

ts_time1 time NOT NULL DEFAULT NOW();
ts_time3 yearNOT NULL DEFAULT NOW();
ts_time2 date NOT NULL DEFAULT CURRENT_TIMESTAMP();
ts_time2 datetime NOT NULL DEFAULT CURRENT_TIMESTAMP();1234

都会报错。所以想要设置某个日期列的默认值为当前时间,只能使用 timestamp 类型,并设置 DEFAULT NOW() 或 DEFAULT CURRENT_TIMESTAMP() 作为默认值。

date 类型默认值使用 current_date() 创建失败

date 创建失败

date 类型默认值使用 now() 创建失败

 date 创建失败2

date 类型默认值使用 current_timestamp() 创建失败

 date 创建失败3

datetime 类型默认值使用 current_timestamp() 创建失败

datetime 创建失败1

datetime 类型默认值使用 now() 创建失败

datetime 创建失败2

timestamp 类型默认值使用 now() 创建成功

timestamp

常见的日期获取函数

MySQL中有一些日期函数可供我们使用,我们可以使用 ” select 函数名() ; ” 的 sql 查看它们的返回值。同时也可以使用 “select 自定义函数名();”,调用我们自己定义的函数。 Eample:

select current_timestamp();

MySQL当前时间戳

select current_date();

MySQL当前日期

select current_time();

当前时间

select now();

获取当前时间

参照“w3School相关内容”,其他常见的日期函数如下

函数 描述
NOW() 返回当前的日期和时间
CURDATE() 返回当前的日期
CURTIME() 返回当前的时间
DATE() 提取日期或日期/时间表达式的日期部分
EXTRACT() 返回日期/时间按的单独部分
DATE_ADD() 给日期添加指定的时间间隔
DATE_SUB() 从日期减去指定的时间间隔
DATEDIFF() 返回两个日期之间的天数
DATE_FORMAT() 用不同的格式显示日期/时间

问题17、所有的视图是否都可以更新?为什么?

(1)若视图的字段是来自字段表达式或常数,则不允许对此视图执行INSERT、UPDATE操作,允许执行DELETE操作; (2)若视图的字段是来自库函数,则此视图不允许更新; (3)若视图的定义中有GROUP BY子句或聚集函数时,则此视图不允许更新; (4)若视图的定义中有DISTINCT任选项,则此视图不允许更新; (5)若视图的定义中有嵌套查询,并且嵌套查询的FROM子句中涉及的表也是导出该视图的基表,则此视图不允许更新; (6)若视图是由两个以上的基表导出的,此视图不允许更新; (7)一个不允许更新的视图上定义的视图也不允许更新; (8)由一个基表定义的视图,只含有基表的主键或候补键,并且视图中没有用表达式或函数定义的属性,才允许更新。 9 .哪类视图是可以更新的?哪类视图是不可更新的?各举一例说明。 答:基本表的行列子集视图一般是可更新的。若视图的属性来自集函数、表达式,则该视图肯定是不可以更新的。

问题18、自动设置create_time和update_time,自动更新

执行后, 会批量更新 现有数据全部自动更新为当前时间, 新插入的数据时候自动更新插入的时间.

CURRENT_TIMESTAMP 字段设置后 当insert数据时 mysql会自动设置当前系统时间 赋值给该属性字段

ON UPDATE CURRENT_TIMESTAMP 字段设置后 当update数据时 并且 成功发生更改时 mysql会自动设置当前系统时间 赋值给该属性字段

# 添加 创建 更新 时间字段
ALTER TABLE `表名`
ADD COLUMN `create_time`  datetime NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER `最后一个列名`,
ADD COLUMN `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP AFTER `create_time`;
# 修改已存在字段.

ALTER TABLE 表名
MODIFY COLUMN create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER create字段前面一个字段名,
MODIFY COLUMN update_time timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP AFTER create_time;

问题19、查询表结构和列注释

1、仅显示表的结构有如下几种方法:

show columns from 表名;
desc 表名;
describe 表名;

2、查询指定数据库中指定表各字段的列注释如下:

select * from information_schema.columns
where TABLE_SCHEMA = '数据库名称'
and TABLE_NAME = '表名称';

3、查询指定数据库中所有表各字段的列注释如下:

select * from information_schema.columns
where TABLE_SCHEMA = '数据库名称';

问题20、mysql获取两个集合的交集/差集/并集

mysql的常见场景,获取两个数据集的交集和差集

步骤

  1. 两个集合的结构要一致,对应的字段数,字段类型
  2. 将两个集合用 UNION ALL 关键字合并,这里的结果是有重复的所有集
  3. 将上面的所有集 GROUP BY id
  4. 最后 HAVING COUNT(id)=1,等于1的意思是只出现了一次,所以这个是差集,如果等于2,那么就是交集

代码演示

差集

-- 下面的sql有明显的问题,不过这个只是一个示意,
-- 从一个表中查询不需要用到交集和差集,条件可以合并在一起直接查询出来的.能明白意思就好
-- 下面的sql的意思是找到所有非技术部的员工的id,code和name
SELECT a.* FROM(
    SELECT id,code,name FROM test_emp
    UNION ALL
    SELECT id,code,name FROM test_emp WHERE dept='JSB'
)a GROUP BY a.id HAVING COUNT(a.id)=1

交集

-- 下面的sql的意思是找到所有技术部年龄大于25的员工
SELECT a.* FROM(
    SELECT id,code,name FROM test_emp WHERE age>25
    UNION ALL
    SELECT id,code,name FROM test_emp WHERE dept='JSB'
)a GROUP BY a.id HAVING COUNT(a.id)=2

并集

-- 下面的sql的意思是找到所有技术部的员工和年龄大于30的员工
-- union可以自动去除重复的内容,得到不重复的结果集
SELECT a.* FROM(
    SELECT id,code,name FROM test_emp WHERE age>25
    UNION
    SELECT id,code,name FROM test_emp WHERE dept='JSB'
)a

21、给已存在的表添加自增主键

alter table alarm_global add id int(11) primary key AUTO_INCREMENT; # 添加自增主键
# 给已存在的字段重新配置主键
alter table alarm_camera_info add global_id int(11);
alter table alarm_robot_info drop PRIMARY KEY ;
alter table alarm_robot_info add PRIMARY KEY(global_id);

22、MySQL运算符 != 和 <> 以及 = 和 <=> 的区别

1、运算符:!= 和 <>

下面查询username为"陈哈哈"以外的用户,以下两条语句的作用一样。

SELECT * FROM t_user WHERE username != "陈哈哈";
SELECT * FROM t_user WHERE username <> "陈哈哈";

2、运算符:= 和 <=>

值得一提的是 = 、 <=> 以及 is 这三个运算符的用法

is 专门用来判断是否为 NULL,而 = 则是用来判断非NULL以外的所有数据类型使用。而 <=> 则是前两者合起来。

<=>运算符相当于封装了= 和 is ,既可以判断 非NULL值,也可以用来判断NULL值。

23、between 的边界问题

between 边界:闭区间,not between 边界:开区间

BETWEEN 用以查询确定范围的值,这些值可以是数字,文本或日期 。

BETWEEN 运算符是闭区间的:包括开始 和 结束值 。

24、varchar类型转换int类型

select * from gyzd_yysinfo order by cast(yysid as SIGNED INTEGER)

一、手动转化类型(直接+0)
select server_id from cardserver where game_id = 1 order by server_id+0 desclimit 10

二、使用MySQL函数CAST
select server_id from cardserver where game_id = 1 order by CAST(server_id as SIGNED) desc limit 10;

三、使用MySQL函数CONVERT
select server_id from cardserver where game_id = 1 order by CONVERT(server_id,SIGNED)desc limit 10;

25、分页查询的SQL语句写法

一:分页需求:

客户端通过传递start(页码),limit(每页显示的条数)两个参数去分页查询数据库表中的数据,那我们知道MySql数据库提供了分页的函数limit m,n,但是该函数的用法和我们的需求不一样,所以就需要我们根据实际情况去改写适合我们自己的分页语句,具体的分析如下:

比如:

查询第1条到第10条的数据的sql是:select * from table limit 0,10; ->对应我们的需求就是查询第一页的数据:select * from table limit (1-1)*10,10;

查询第10条到第20条的数据的sql是:select * from table limit 10,20; ->对应我们的需求就是查询第二页的数据:select * from table limit (2-1)*10,10;

查询第20条到第30条的数据的sql是:select * from table limit 20,30; ->对应我们的需求就是查询第三页的数据:select * from table limit (3-1)*10,10;

二:通过上面的分析,可以得出符合我们自己需求的分页sql格式是:

select * from table limit (start-1)*limit,limit; 

其中start是页码,limit是每页显示的条数。