MySQL 疑难 SQL
原文链接: MySQL 疑难 SQL
- content
{:toc}
指定IP和端口
mysql -uroot -p -h192.168.3.146 -P3306
时间自动更新
ALTER TABLE `tb_user` CHANGE `modified_time` `modified_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
补充自增主键
alter table `表格名` add column `列名` int not null auto_increment primary key comment '主键' first;
分组排序取前N条记录
建表并初始化数据:
CREATE TABLE lin(
id integer NOT NULL,
type varchar(1) ,
CONSTRAINT lin_pkey PRIMARY KEY (id)
);
INSERT INTO lin(id, type) VALUES (1, 'a'),(2, 'a'),(3, 'a'),(4, 'b'),(5, 'b'),(6, 'b'),(7, 'b'),(8, 'c'),(9, 'c'),(10, 'c');
执行查询:
select * from lin a where (select count(1) from lin b where a.type = b.type and a.id < b.id) < 2
执行结果为:
+----+------+
| id | type |
+----+------+
| 2 | a |
| 3 | a |
| 6 | b |
| 7 | b |
| 9 | c |
| 10 | c |
+----+------+
SQL解释:
- 子查询是查询所有和当前记录type一样但是id比当前记录大的记录的总和
- type和当前记录一样,但是id比当前记录大的记录如果大于或者等于两个,说明当前至少排在第三个
- type和当前记录一样,但是id比当前记录大的记录如果小于两个,说明当前记录可以排在前两个
查询结果加序号
select (@i:=@i+1) num,u.user_name from tb_user u,(select @i:=0) t
MySQL变量不用事前声明,只需要“@变量名”使用即可
LPAD
find_in_set
日期
时间函数
select now(), sysdate(), curdate(), curtime(); "now()": "2018-01-06 10:05:19", "sysdate()": "2018-01-06 10:05:19", "curdate()": "2018-01-06", "curtime()": "10:05:19"
now()和sysdate()的区别
now() 在执行开始时值就得到了,sysdate() 在函数执行时动态获取值MariaDB [(none)]> select sysdate(), sleep(3), sysdate(); +---------------------+----------+---------------------+ | sysdate() | sleep(3) | sysdate() | +---------------------+----------+---------------------+ | 2018-01-12 17:23:05 | 0 | 2018-01-12 17:23:08 | +---------------------+----------+---------------------+ 1 row in set (3.01 sec) MariaDB [(none)]> select now(), sleep(3), now(); +---------------------+----------+---------------------+ | now() | sleep(3) | now() | +---------------------+----------+---------------------+ | 2018-01-12 17:23:13 | 0 | 2018-01-12 17:23:13 | +---------------------+----------+---------------------+ 1 row in set (3.00 sec)
日期和毫秒数转换
select UNIX_TIMESTAMP('2018-01-06 10:04:30'); select from_unixtime(1515204270);
为日期增加/减少时间间隔
select date_add(now(), interval 1 day); select date_add(now(), interval -1 day); 增加/减少的时间单位可选: day、hour、minute、second、microsecond、week、month、quarter、year
中文排序
GBK编码时一级汉字3755个采用拼音排序,二级汉字不是
但考虑到常用汉字都是一级汉字,所以中文排序依赖GBK编码基本上可以满足需求
若数据库采用GBK编码,则直接order by [field] desc/asc
即可
若数据库采用utf8编码,则使用order by convert([field] using gbk) desc/asc
即可
示例:
INSERT INTO `tb_order` (`id`, `name`) VALUES
(1,'赵'),
(2,'钱'),
(3,'孙'),
(4,'李'),
(5,'赵赵'),
(6,'赵钱'),
(7,'赵孙'),
(8,'赵李'),
(9,'啦'),
(10,'lb'),
(11,'la');
结果如下:
MariaDB [learn]> select * from tb_order order by convert(name using gbk) asc;
+----+--------+
| id | name |
+----+--------+
| 11 | la |
| 10 | lb |
| 9 | 啦 |
| 4 | 李 |
| 2 | 钱 |
| 3 | 孙 |
| 1 | 赵 |
| 8 | 赵李 |
| 6 | 赵钱 |
| 7 | 赵孙 |
| 5 | 赵赵 |
+----+--------+