那些年咱們一塊兒追過的稀奇古怪的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的版本是兼容的。
相關文章
相關標籤/搜索