那些年咱们一块儿追过的稀奇古怪的SQL

好久没写博客了,快过年了,今天工做比较轻松,晚上把以前的一些积累的东西整理一下 java

文章的题目是个人一个小分享,主要是收集了一些不太经常使用的sql语法。打算以后作一个oracle的姊妹篇。 mysql

ADELETE语法 sql

1 delete能够和orderby及limit同时使用,比较适用于删除某种排序时的前若干条记录 shell

DELETE  FROM `city` where CountryCode='AFG' ORDER BY ID limit 1;

另外这条语句锁表的话是锁全表仍是只锁一行? 数据库

答案是只锁一行,验证以下: 服务器

会话1:delete from tttt order by id limit 1;
会话2:select * from tttt where id =7 for update; -->锁住
select * from tttt where id =9 for update -->没有锁住
2 delete但是适用LOW_PRIORITY关键字

若是指定LOW_PRIORITY,则DELETE的执行被延迟,直到没有其它客户端读取本表时再执行 oracle

3 delete可使用QUICK关键字 函数

对于MyISAM表,若是您使用QUICK关键词,则在删除过程当中,存储引擎不会合并索引端结点,这样能够加快部分种类的删除操做的速度 spa

4 delete可使用IGNORE关键字 线程

在删除行的过程当中,IGNORE关键词会使MySQL忽略全部的错误。(在分析阶段遇到的错误会以常规方式处理。)因为使用本选项而被忽略的错误会做为警告返回。

5 若是删除了auto_increment最大的字段,那么下次再插入的时候是否会重复使用这个最大字段?

myisam及innodb不会重复适用,bdb会从新用这个字段

6 多表删除没有order by及limit的关键字

7 多表删除支持*的语法,若是删除的字段不是*,是具体的某个字段能够么?

是不能够的,是会报错的

DELETE city.CountryCode, countrylanguage.* FROM country, city, countrylanguage WHERE city.CountryCode = country.`Code` AND countrylanguage.CountryCode = country.`Code` AND country.`Code` = 'AFG'
Unknown table 'countrycode' in MULTI DELETE
B INSERT语法

1 insert可使用DELAYED关键字

若是您使用DELAYED关键字,则服务器会把待插入的行放到一个缓冲器中,而发送INSERT DELAYED语句的客户端会继续运行。若是表正在被使用,则服务器会保留这些行。当表空闲时,服务器开始插入行,并按期检查是否有新的读取请求。若是有新的读取请求,则被延迟的行被延缓执行,直到表再次空闲时为止。

客户端使用INSERT DELAYED时,会马上从服务器处获得一个肯定。而且行被排入队列,当表没有被其它线程使用时,此行被插入。另外 INSERT DELAYED仅适用于MyISAM, MEMORY和ARCHIVE表。

与delead有关的一些参数以下:

show status like '%Delayed%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| Delayed_errors | 0 |
| Delayed_insert_threads | 0 |
| Delayed_writes | 0 |
| Not_flushed_delayed_rows | 0 |
+--------------------------+-------+
2 insert能够什么都不写进行插入,前提是字段不能有非空限定或者有默认值,以下的语句也是能够的,会插入一行空值
INSERT INTO tbl_name () VALUES()
3 insert中没有and关键字,可是下面的语句也不会报错,只是会有逻辑错误


insert into tttt set name='1' and name='3' ,age=3
4 insert有ON DUPLICATE KEY UPDATE的用法,若是插入行致使一个unique索引或者主键冲突而致使插入失败后,on duplicate key 后面的语句依旧会执行
insert into tttt set id=1 ,name='name3' ,age=5 
on DUPLICATE key update age=age*3;
插入时遇到id冲突 依旧会执行 age×3的操做

5 ON DUPLICATE KEY UPDATE语法支持values()函数

insert into tttt set id=1 ,name='name3' ,age=5
on DUPLICATE key update age=VALUES(id);
6 insert ...select语法没有 DELAYED关键字

C REPLACE语法

1 replace语法的流程以下:

若是表中的一个旧记录与一个用于PRIMARY KEY或一个UNIQUE索引的新记录具备相同的值,则在新记录被插入以前,旧记录被删除
尝试把新行插入到表中
当由于对于主键或惟一关键字出现重复关键字错误而形成插入失败时:
a.    从表中删除含有重复关键字值的冲突行
b.    再次尝试把新行插入到表中
2若是replace的时候同时发生了主键及惟一键冲突的时候会执行什么操做?
REPLACE into tttt set id =1 ,name='name5'
会有id和name同时冲突的话,原有的id=1的id=2,name=name5的数据被删除,只保留一条id=1 ,name=name5的数据

D SELECT语法

1 别名的AS是能够选择使用的,别名用于gruop by,order by 和having中是能够的

SELECT id as num,CONCAT(CountryCode,'*',District) AS t from city where num>6
select中的别名用于gruop by,order by 和having中,若是别名和现有字段冲突会优先使用别名
SELECT MAX(Population) as ID FROM `city` GROUP BY CountryCode HAVING id>669181;
city表中已经有了ID字段,咱们强制把 population别名为ID,在having中使用ID做为分组条件,结果显示使用别名表明的字段即max(population)做为过滤条件

2 order by, group by 可使用列位置

SELECT id  from city ORDER BY 1

3 group by也能够排序

SELECT a, COUNT(b) FROM test_table GROUP BY a DESC
4 limit可使用OFFSET关键字
SELECT *  from city LIMIT 1 OFFSET 10;
SELECT *  from city LIMIT 10,1;
这两个语句是等价的


5 在使用行子查询的时候可使用ROW关键字

SELECT * FROM t1 WHERE (1,2) = (SELECT column1, column2 FROM t2);
SELECT * FROM t1 WHERE ROW(1,2) = (SELECT column1, column2 FROM t2);
6 select中有SQL_CALC_FOUND_ROW关键字,作分页的时候很好用,其好处就是只查询一次数据库,效率提升了一半,其用法以下:
SELECT * FROM city;
SELECT FOUND_ROWS();
总结一下,本文列出了一些mysql中容易被忽略的语法,主要是inert,delete,replace及select,update的语法规则与前面几个相像,因此没有找到特殊的用法,本文的语法规则主要以mysql5.1为准,与5.5的版本是兼容的。
相关文章
相关标签/搜索