1凌节、distinct :
去重钦听,必須放在開頭洒试,有多個(gè)列時(shí),是多列去重朴上。
2垒棋、concat():
拼接串,多個(gè)串連接成一個(gè)串痪宰。
3叼架、Trim():
去掉左右多余空格,RTrim()去右邊多余空格衣撬。LTrim()去掉左邊多余空格乖订。
IFNULL():IFNULL() 函數(shù)用于判斷第一個(gè)表達(dá)式是否為 NULL,如果為 NULL 則返回第二個(gè)參數(shù)的值具练,如果不為 NULL 則返回第一個(gè)參數(shù)的值乍构。
IFNULL(expression, alt_value)
4、時(shí)間函數(shù)
函 數(shù) | 說 明 |
---|---|
AddDate() |
增加一個(gè)日期(天扛点、周等) |
AddTime() |
增加一個(gè)時(shí)間(時(shí)哥遮、分等) |
CurDate() |
返回當(dāng)前日期 |
CurTime() |
返回當(dāng)前時(shí)間 |
Date() |
返回日期時(shí)間的日期部分 |
DateDiff() |
計(jì)算兩個(gè)日期之差 |
Date_Add() |
高度靈活的日期運(yùn)算函數(shù) |
Date_Format() |
返回一個(gè)格式化的日期或時(shí)間串 |
Day() |
返回一個(gè)日期的天數(shù)部分 |
DayOfWeek() |
對(duì)于一個(gè)日期,返回對(duì)應(yīng)的星期幾 |
Hour() |
返回一個(gè)時(shí)間的小時(shí)部分 |
Minute() |
返回一個(gè)時(shí)間的分鐘部分 |
Month() |
返回一個(gè)日期的月份部分 |
Now() |
返回當(dāng)前日期和時(shí)間 |
Second() |
返回一個(gè)時(shí)間的秒部分 |
Time() |
返回一個(gè)日期時(shí)間的時(shí)間部分 |
Year() |
返回一個(gè)日期的年份部分 |
5陵究、數(shù)值處理函數(shù)
函 數(shù) | 說 明 |
---|---|
Abs() |
返回一個(gè)數(shù)的絕對(duì)值 |
Cos() |
返回一個(gè)角度的余弦 |
Exp() |
返回一個(gè)數(shù)的指數(shù)值 |
Mod() |
返回除操作的余數(shù) |
Pi() |
返回圓周率 |
Rand() |
返回一個(gè)隨機(jī)數(shù) |
Sin() |
返回一個(gè)角度的正弦 |
Sqrt() |
返回一個(gè)數(shù)的平方根 |
Tan() |
返回一個(gè)角度的正切 |
6昔善、聚集函數(shù)
函 數(shù) | 說 明 |
---|---|
AVG() |
返回某列的平均值(忽略值為NULL 的行) |
COUNT() |
返回某列的行數(shù)COUNT(*) 不管表列中包含的是空值(NULL )還是非空值COUNT(column) 忽略NULL 值 |
MAX() |
返回某列的最大值(忽略NULL ) |
MIN() |
返回某列的最小值 |
SUM() |
返回某列值之和(忽略NULL ) |
若在聚集函數(shù)中需要忽略相同值可以用COUNT(distinct a)
。
7畔乙、分組數(shù)據(jù)
GROUP BY
子句可以包含任意數(shù)目的列。這使得能對(duì)分組進(jìn)行嵌套翩概,為數(shù)據(jù)分組提供更細(xì)致的控制牲距。
GROUP BY
列出的每個(gè)列都要死檢索列或有效的表達(dá)式,不能是聚集函數(shù)钥庇。
如果分組列中有NULL
值牍鞠,則NULL
值作為一個(gè)分組返回,多個(gè)NULL
將被分為一組评姨。
GROUP BY
子句必須出現(xiàn)在WHERE
子句之后难述,ORDER BY
子句之前。
使用ROLLUP
:使用WITH ROLLUP
關(guān)鍵字吐句,可以在最后一行列出所有分組的總和胁后。
8、過濾分組
HAVING
和WHERE
的差別:WHERE
在數(shù)據(jù)分組前進(jìn)行過濾嗦枢,HAVING
在分組后進(jìn)行過濾攀芯。大前提是WHERE
排除的行不在分組中。
9文虏、SELECT
子句及其順序
子 句 | 說 明 | 是否必須使用 |
---|---|---|
SELECT |
要返回的列或表達(dá)式 | 是 |
FROM |
從中檢索數(shù)據(jù)的表 | 僅在從表選擇數(shù)據(jù)時(shí)使用 |
WHERE |
行級(jí)過濾 | 否 |
GROUP BY |
分組說明 | 僅在按組計(jì)算聚集時(shí)使用 |
HAVING |
組級(jí)過濾 | 否 |
ORDER BY |
輸出排序順序 | 否 |
LIMIT |
要檢索的行數(shù) | 否 |
10侣诺、子查詢
列必須匹配:在WHERE
子句中使用子查詢殖演,應(yīng)該保證SELECT
語(yǔ)句具有與WHERE
子句中相同數(shù)目的列。通常年鸳,子查詢將返回單個(gè)列并且與單個(gè)列匹配趴久,但如果需要也可以使用多個(gè)列。
相關(guān)子查詢:涉及外部查詢的子查詢搔确。這種類型的子查詢稱為相關(guān)子查詢彼棍。任何時(shí)候只要列名可能有多義性,就必須使用這種語(yǔ)法比如:
SELECT cust_name, cust_state,
(SELECT COUNT(*) FROM orders
WHERE orders.cust_id = customers.cust_id) AS orders
FROM customers ORDER BY cust_name;
中的WHERE orders.cust_id = customers.cust_id
妥箕。
11滥酥、聯(lián)結(jié)
-
等值聯(lián)結(jié)(內(nèi)部聯(lián)結(jié))
SQL
最強(qiáng)大的功能之一就是能在數(shù)據(jù)檢索查詢的執(zhí)行中聯(lián)結(jié)表。聯(lián)結(jié)是利用SQL
的SELECT
能執(zhí)行的最重要的操作畦幢,很好地理解聯(lián)結(jié)及其語(yǔ)法是學(xué)習(xí)SQL
的一個(gè)極為重要的組成部分坎吻。笛卡兒積(cartesianproduct) 由沒有聯(lián)結(jié)條件的表關(guān)系返回的結(jié)果為笛卡兒積。檢索出的行的數(shù)目將是第一個(gè)表中的行數(shù)乘以第二個(gè)表中的行數(shù)宇葱。
比如:
SELECT vend_name, prod_name, prod_price FROM vendors,products#沒有用where限定條件瘦真,會(huì)輸出(預(yù)定義venders表有a行,products有b行)a*b行黍瞧。 ORDER BY vend_name, prod_name;
使用inner join
比如:
SELECT vend_name, prod_name, prod_price
FROM vendors INNER JOIN products
ON vendors.vend_id = products.vend_id;
ANSI SQL規(guī)范首選INNER JOIN
語(yǔ)法诸尽。此外,盡管使用WHERE
子句定義聯(lián)結(jié)的確比較簡(jiǎn)單印颤,但是使用明確的聯(lián)結(jié)語(yǔ)法能夠確保不會(huì)忘記聯(lián)結(jié)條件您机,有時(shí)候這樣做也能影響性能。
性能考慮 MySQL在運(yùn)行時(shí)關(guān)聯(lián)指定的每個(gè)表以處理聯(lián)結(jié)年局。這種處理可能是非常耗費(fèi)資源的际看,因此應(yīng)該仔細(xì),不要聯(lián)結(jié)不必要的表矢否。聯(lián)結(jié)的表越多仲闽,性能下降越厲害。
另外僵朗,部分子查詢可以改成聯(lián)結(jié)查詢赖欣,聯(lián)結(jié)查詢更快,因?yàn)樽硬樵儠?huì)創(chuàng)建臨時(shí)表验庙,查詢完畢后再刪除臨時(shí)表顶吮,子查詢速度較慢。
-
自聯(lián)結(jié)
自聯(lián)結(jié)粪薛,就是用表別名的方式將一個(gè)表假設(shè)為兩張一樣的表云矫,做多表查詢。
現(xiàn)在有一個(gè)情景:一個(gè)表,里面有商品id:
prod_id
让禀,商品名:prod_name
挑社,供應(yīng)商id:vend_id
,表名:products
巡揍。假如你發(fā)現(xiàn)某物品(其ID為
DTNTR
)存在問題痛阻,想知道生產(chǎn)該物品的供應(yīng)商生產(chǎn)的其他物品是否有問題。要查詢這個(gè)供應(yīng)商生產(chǎn)的所有物品腮敌,怎么查詢阱当?SELECT p1.prod_id, p1.prod_name FROM products AS p1, products AS p2 WHERE p1.vend_id = p2.vend_id AND p2.prod_id = 'DTNTR';
-
自然聯(lián)結(jié)
無論何時(shí)對(duì)表進(jìn)行聯(lián)結(jié),應(yīng)該至少有一個(gè)列出現(xiàn)在不止一個(gè)表中(被聯(lián)結(jié)的列)糜工。標(biāo)準(zhǔn)的聯(lián)結(jié)返回所有數(shù)據(jù)弊添,甚至相同的列多次出現(xiàn)。自然聯(lián)結(jié)排除多次出現(xiàn)捌木,使每個(gè)列只返回一次油坝。
自然聯(lián)結(jié)是這樣一種聯(lián)結(jié),其中你只能選擇那些唯一的列刨裆。這一般是通過對(duì)表使用通配符(
SELECT *
)澈圈,對(duì)所有其他表的列使用明確的子集來完成的。 -
外部聯(lián)結(jié)
左外部聯(lián)結(jié)(又叫左聯(lián)結(jié))
左表的行一定會(huì)列出帆啃,右表如果沒有匹配的行瞬女,那么列值就為
NULL
。特別需要注意的是如果右表有多行和左表匹配努潘,那么左表相同的行會(huì)出現(xiàn)多次
例子:
select a.f1,b.f2 from a left outer join b on a.f3=b.f4(outer關(guān)鍵字可以省略)
右外部聯(lián)結(jié)(又叫右聯(lián)結(jié))
和左聯(lián)結(jié)類似诽偷,只不過以右表為主表而已,左聯(lián)結(jié)和右聯(lián)結(jié)可以相互轉(zhuǎn)化疯坤。
select a.f1,b.f2 from a right outer join b on a.f3=b.f4(outer關(guān)鍵字可以省略)
全外部聯(lián)結(jié)
返回左表和右表的所有行报慕,不管有沒有匹配,同時(shí)具有左聯(lián)結(jié)和右聯(lián)結(jié)的特性贴膘。
select a.f1,b.f2 from a full outer join b on a.f3=b.f4(outer關(guān)鍵字可以省略)
關(guān)于聯(lián)結(jié)的示意圖:
[圖片上傳失敗...(image-e6a470-1589365058282)]
12、組合查詢
可用UNION
操作符來組合數(shù)條SQL查詢略号。利用UNION
刑峡,可給出多條SELECT
語(yǔ)句,將它們的結(jié)果組合成單個(gè)結(jié)果集玄柠。
比如:
SELECT vend_id, prod_id, prod_price
FROM products
WHERE prod_price <= 5
UNION
SELECT vend_id, prod_id, prod_price
FROM products
WHERE vend_id IN (1001,1002);
UNION規(guī)則:
-
UNION
必須由兩條或兩條以上的SELECT
語(yǔ)句組成突梦,語(yǔ)句之間用關(guān)鍵字UNION
分隔(因此,如果組合4條SELECT
語(yǔ)句羽利,將要使用3個(gè)UNION
關(guān)鍵字)宫患。 -
UNION
中的每個(gè)查詢必須包含相同的列、表達(dá)式或聚集函數(shù)(不過各個(gè)列不需要以相同的次序列出)这弧。 - 列數(shù)據(jù)類型必須兼容:類型不必完全相同娃闲,但必須是DBMS可以隱含地轉(zhuǎn)換的類型(例如虚汛,不同的數(shù)值類型或不同的日期類型)。
UNION從查詢結(jié)果集中會(huì)自動(dòng)去除重復(fù)的行皇帮。(不分字段的類型卷哩,只要值一樣就去重)
如果想返回所有匹配行,可使用UNION ALL
而不是UNION
属拾。
在用UNION
組合查詢時(shí)将谊,只能使用一條ORDER BY
子句,它必須出現(xiàn)在最后一條SELECT
語(yǔ)句之后渐白。
13尊浓、全文本搜索
并非所有引擎都支持全文本搜索,MyISAM支持全文本搜索纯衍。
為了進(jìn)行全文本搜索栋齿,必須索引被搜索的列,而且要隨著數(shù)據(jù)的改變不斷地重新索引托酸。在對(duì)表列進(jìn)行適當(dāng)設(shè)計(jì)后褒颈,MySQL會(huì)自動(dòng)進(jìn)行所有的索引和重新索引。
一般在創(chuàng)建表時(shí)啟用全文本搜索励堡。CREATE TABLE
語(yǔ)句接受FULLTEXT
子句谷丸,它給出被索引列的一個(gè)逗號(hào)分隔的列表。
例如:
CREATE TABLE productnotes
(
note_id int NOT NULL AUTO_INCREMENT,
prod_id char(10) NOT NULL,
note_date datetime NOT NULL,
note_text text NULL ,
PRIMARY KEY(note_id),
FULLTEXT(note_text)
) ENGINE=MyISAM;
這些列中有一個(gè)名為note_text
的列应结,為了進(jìn)行全文本搜索刨疼,MySQL根據(jù)子句FULLTEXT(note_text)
的指示對(duì)它進(jìn)行索引。這里的FULLTEXT
索引單個(gè)列鹅龄,如果需要也可以指定多個(gè)列揩慕。
在定義之后,MySQL自動(dòng)維護(hù)該索引扮休。在增加迎卤、更新或刪除行時(shí),索引隨之自動(dòng)更新玷坠。
不要在導(dǎo)入數(shù)據(jù)時(shí)使用FULLTEXT 更新索引要花時(shí)間蜗搔,雖然不是很多,但畢竟要花時(shí)間八堡。如果正在導(dǎo)入數(shù)據(jù)到一個(gè)新表樟凄,此時(shí)不應(yīng)該啟用FULLTEXT
索引。應(yīng)該首先導(dǎo)入所有數(shù)據(jù)兄渺,然后再修改表缝龄,定義FULLTEXT
。這樣有助于更快地導(dǎo)入數(shù)據(jù)(而且使索引數(shù)據(jù)的總時(shí)間小于在導(dǎo)入每行時(shí)分別進(jìn)行索引所需的總時(shí)間)。
在索引之后叔壤,使用兩個(gè)函數(shù)Match()
和Against()
執(zhí)行全文本搜索瞎饲,其中Match()
指定被搜索的列,Against()
指定要使用的搜索表達(dá)式百新。
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against('rabbit');
14企软、插入數(shù)據(jù)
插入多行
INSERT INTO customers(cust_name,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country)
VALUES(
'Pep E. LaPew',
'100 Main Street',
'Los Angeles',
'CA',
'90046',
'USA'
),
(
'M. Martian',
'42 Galaxy Way',
'New York',
'NY',
'11213',
'USA'
);
提高INSERT的性能 此技術(shù)可以提高數(shù)據(jù)庫(kù)處理的性能,因?yàn)镸ySQL用單條INSERT
語(yǔ)句處理多個(gè)插入比使用多條INSERT
語(yǔ)句快饭望。
插入檢索出的數(shù)據(jù)
這個(gè)例子把一個(gè)名為custnew
的表中的數(shù)據(jù)導(dǎo)入customers
表中仗哨。
INSERT INTO customers(cust_id,
cust_contact,
cust_email,
cust_name,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country)
SELECT cust_id,
cust_contact,
cust_email,
cust_name,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country
FROM custnew;
15、更新數(shù)據(jù)
不要省略WHERE
子句 在使用UPDATE
時(shí)一定要注意細(xì)心铅辞。因?yàn)樯圆蛔⒁庋崞蜁?huì)更新表中所有行。
例如:
UPDATE customers
SET cust_email = 'elmer@fudd.com'
WHERE cust_id = 10005;
在UPDATE
語(yǔ)句中使用子查詢 UPDATE
語(yǔ)句中可以使用子查詢斟珊,使得能用SELECT
語(yǔ)句檢索出的數(shù)據(jù)更新列數(shù)據(jù)苇倡。
IGNORE
關(guān)鍵字 如果用UPDATE
語(yǔ)句更新多行,并且在更新這些行中的一行或多行時(shí)出一個(gè)現(xiàn)錯(cuò)誤囤踩,則整個(gè)UPDATE
操作被取消(錯(cuò)誤發(fā)生前更新的所有行被恢復(fù)到它們?cè)瓉淼闹担┲冀贰榧词故前l(fā)生錯(cuò)誤,也繼續(xù)進(jìn)行更新堵漱,可使用IGNORE
關(guān)鍵字综慎。
16、刪除數(shù)據(jù)
例子:
DELETE FROM customers
WHERE cust_id = 10006;
更快的刪除 如果想從表中刪除所有行勤庐,不要使用DELETE
示惊。可使用TRUNCATE TABLE
語(yǔ)句愉镰,它完成相同的工作米罚,但速度更快(TRUNCATE
實(shí)際是刪除原來的表并重新創(chuàng)建一個(gè)表,而不是逐行刪除表中的數(shù)據(jù))丈探。
17录择、創(chuàng)建和操縱表
處理現(xiàn)有的表 在創(chuàng)建新表時(shí),指定的表名必須不存在碗降,否則將出錯(cuò)隘竭。如果你僅想在一個(gè)表不存在時(shí)創(chuàng)建它,應(yīng)該在表名前給出IF NOT EXISTS
遗锣。這樣做不檢查已有表的模式是否與你打算創(chuàng)建的表模式相匹配货裹。它只是查看表名是否存在嗤形,并且僅在表名不存在時(shí)創(chuàng)建它精偿。
默認(rèn)值
默認(rèn)值用CREATE TABLE語(yǔ)句的列定義中的DEFAULT關(guān)鍵字指定。
quantity int NOT NULL DEFAULT 1,
與大多數(shù)DBMS不一樣,MySQL不允許使用函數(shù)作為默認(rèn)值笔咽,它只支持常量搔预。許多數(shù)據(jù)庫(kù)開發(fā)人員使用默認(rèn)值而不是NULL列,特別是對(duì)用于計(jì)算或數(shù)據(jù)分組的列更是如此叶组。
數(shù)據(jù)庫(kù)引擎
MySQL有一個(gè)具體管理和處理數(shù)據(jù)的內(nèi)部引擎拯田。在你使用CREATE TABLE語(yǔ)句時(shí),該引擎具體創(chuàng)建表甩十,而在你使用SELECT語(yǔ)句或進(jìn)行其他數(shù)據(jù)庫(kù)處理時(shí)船庇,該引擎在內(nèi)部處理你的請(qǐng)求。多數(shù)時(shí)候侣监,此引擎都隱藏在DBMS內(nèi)鸭轮,不需要過多關(guān)注它。MySQL與其他DBMS不一樣橄霉,它具有多種引擎窃爷。它打包多個(gè)引擎,這些引擎都隱藏在MySQL服務(wù)器內(nèi)姓蜂,全都能執(zhí)行CREATE TABLE和SELECT等命令按厘。
以下是幾個(gè)需要知道的引擎:
InnoDB是一個(gè)可靠的事務(wù)處理引擎,它不支持全文本搜索钱慢;
MEMORY在功能等同于MyISAM逮京,但由于數(shù)據(jù)存儲(chǔ)在內(nèi)存(不是磁盤)中,速度很快(特別適合于臨時(shí)表)滩字;
MyISAM是一個(gè)性能極高的引擎造虏,它支持全文本搜索,但不支持事務(wù)處理麦箍。
引擎類型可以混用漓藕。比如一個(gè)表使用MyISAM外,其他表都使用InnoDB挟裂。但是要注意外鍵不能跨引擎享钞,即使用一個(gè)引擎的表不能引用具有使用不同引擎的表的外鍵。
更新表
使用ALTER TABLE
更改表結(jié)構(gòu)诀蓉,必須給出下面的信息:
- 在
ALTER TABLE
之后給出要更改的表名(該表必須存在栗竖,否則將出錯(cuò)); - 所做更改的列表渠啤。
ALTER TABLE
的一種常見用途是定義外鍵狐肢。下面是用來定義本書中的表所用的外鍵的代碼:
ALTER TABLE orderitems
ADD CONSTRAINT fk_orderitems_orders
FOREIGN KEY (order_num) REFERENCES orders (order_num);
ALTER TABLE orderitems
ADD CONSTRAINT fk_orderitems_products FOREIGN KEY (prod_id)
REFERENCES products (prod_id);
ALTER TABLE orders
ADD CONSTRAINT fk_orders_customers FOREIGN KEY (cust_id)
REFERENCES customers (cust_id);
ALTER TABLE products
ADD CONSTRAINT fk_products_vendors
FOREIGN KEY (vend_id) REFERENCES vendors (vend_id);
這里,由于要更改4個(gè)不同的表沥曹,使用了4條ALTER TABLE
語(yǔ)句份名。為了對(duì)單個(gè)表進(jìn)行多個(gè)更改碟联,可以使用單條ALTER TABLE
語(yǔ)句,每個(gè)更改用逗號(hào)分隔僵腺。
重命名表
使用RENAME TABLE
語(yǔ)句可以重命名一個(gè)表:
RENAME TABLE customers2 TO customers;
多個(gè)表重命名:
RENAME TABLE backup_customers TO customers,
backup_vendors TO vendors,
backup_products TO products;
18鲤孵、視圖
關(guān)于視圖創(chuàng)建和使用的一些最常見的規(guī)則和限制:
- 與表一樣,視圖必須唯一命名(不能給視圖取與別的視圖或表相同的名字)辰如。
- 對(duì)于可以創(chuàng)建的視圖數(shù)目沒有限制普监。
- 為了創(chuàng)建視圖,必須具有足夠的訪問權(quán)限琉兜。這些限制通常由數(shù)據(jù)庫(kù)管理人員授予凯正。
- 視圖可以嵌套,即可以利用從其他視圖中檢索數(shù)據(jù)的查詢來構(gòu)造一個(gè)視圖豌蟋。
-
ORDER BY
可以用在視圖中漆际,但如果從該視圖檢索數(shù)據(jù)SELECT
中也含有ORDER BY
,那么該視圖中的ORDER BY
將被覆蓋夺饲。 - 視圖不能索引奸汇,也不能有關(guān)聯(lián)的觸發(fā)器或默認(rèn)值。
- 視圖可以和表一起使用往声。例如擂找,編寫一條聯(lián)結(jié)表和視圖的
SELECT
語(yǔ)句。
性能問題 因?yàn)橐晥D不包含數(shù)據(jù)浩销,所以每次使用視圖時(shí)贯涎,都必須處理查詢執(zhí)行時(shí)所需的任一個(gè)檢索。如果你用多個(gè)聯(lián)結(jié)和過濾創(chuàng)建了復(fù)雜的視圖或者嵌套了視圖慢洋,可能會(huì)發(fā)現(xiàn)性能下降得很厲害塘雳。因此,在部署使用了大量視圖的應(yīng)用前普筹,應(yīng)該進(jìn)行測(cè)試败明。
視圖的創(chuàng)建:
- 視圖用
CREATE VIEW
語(yǔ)句來創(chuàng)建。 - 使用
SHOW CREATE VIEW viewname;
來查看創(chuàng)建視圖的語(yǔ)句太防。 - 用
DROP
刪除視圖妻顶,其語(yǔ)法為DROP VIEW viewname;
。 - 更新視圖時(shí)蜒车,可以先用
DROP
再用CREATE
讳嘱,也可以直接用CREATE OR REPLACE VIEW
。如果要更新的視圖不存在酿愧,則第2條更新語(yǔ)句會(huì)創(chuàng)建一個(gè)視圖沥潭;如果要更新的視圖存在,則第2條更新語(yǔ)句會(huì)替換原有視圖嬉挡。
語(yǔ)法格式如下:
CREATE VIEW <視圖名> AS <SELECT語(yǔ)句>
對(duì)于創(chuàng)建視圖中的 SELECT 語(yǔ)句的指定存在以下限制:
- 用戶除了擁有 CREATE VIEW 權(quán)限外钝鸽,還具有操作中涉及的基礎(chǔ)表和其他視圖的相關(guān)權(quán)限呼渣。
- SELECT 語(yǔ)句不能引用系統(tǒng)或用戶變量。
- SELECT 語(yǔ)句不能包含 FROM 子句中的子查詢寞埠。
- SELECT 語(yǔ)句不能引用預(yù)處理語(yǔ)句參數(shù)。
19焊夸、limit和offset的區(qū)別
SQL查詢語(yǔ)句中的 limit 與 offset 的區(qū)別:
-
limit y
分句表示: 讀取 y 條數(shù)據(jù) -
limit x, y
分句表示: 跳過 x 條數(shù)據(jù)仁连,讀取 y 條數(shù)據(jù) -
limit y offset x
分句表示: 跳過 x 條數(shù)據(jù),讀取 y 條數(shù)據(jù)
比如分頁(yè)獲取數(shù)據(jù):
第1頁(yè): 從第0個(gè)開始阱穗,獲取20條數(shù)據(jù)
select * from testtable limit 0, 20;
select * from testtable limit 20 offset 0;
第2頁(yè): 從第20個(gè)開始饭冬,獲取20條數(shù)據(jù)
select * from testtable limit 20, 20;
select * from testtable limit 20 offset 20;
第3頁(yè): 從第40個(gè)開始,獲取20條數(shù)據(jù)
select * from testtable limit 40, 20;
select * from testtable limit 20 offset 40;
20揪阶、CHAR和VARCHAR的區(qū)別
CHAR和VARCHAR的主要區(qū)別有三方面:
- 最大長(zhǎng)度
- 有效長(zhǎng)度
- 存儲(chǔ)方式
- 是否保留末尾空格
最大長(zhǎng)度
- CHAR的長(zhǎng)度范圍為0~255
- VARCHAR的長(zhǎng)度范圍為0~65535
有效長(zhǎng)度
- CHAR的長(zhǎng)度按照聲明的長(zhǎng)度保持不變
- VARCHAR的長(zhǎng)度是可變的昌抠,VARCHAR數(shù)據(jù)的有效長(zhǎng)度應(yīng)在聲明時(shí)指定的長(zhǎng)度范圍內(nèi)
- 當(dāng)插入的數(shù)據(jù)超出CHAR或VARCHAR聲明的長(zhǎng)度時(shí),非嚴(yán)格模式會(huì)報(bào)警告并截?cái)鄶?shù)據(jù)鲁僚,嚴(yán)格模式下會(huì)報(bào)錯(cuò)
- 當(dāng)插入的數(shù)據(jù)超出CHAR或VARCHAR聲明的長(zhǎng)度炊苫,且當(dāng)超出的部分僅為數(shù)據(jù)末尾空格時(shí),無論何種模式下冰沙,CHAR型數(shù)據(jù)會(huì)截?cái)鄶?shù)據(jù)且不提示任何信息侨艾,而VARCHAR型數(shù)據(jù)會(huì)截?cái)鄶?shù)據(jù)但報(bào)警告
存儲(chǔ)方式
-
CHAR型數(shù)據(jù)僅存儲(chǔ)數(shù)據(jù)本身;
VARCHAR型數(shù)據(jù)的存儲(chǔ)方式為:1~2字節(jié)的長(zhǎng)度前綴 + 數(shù)據(jù)拓挥;
-
CHAR型數(shù)據(jù)存儲(chǔ)時(shí)唠梨,若數(shù)據(jù)的長(zhǎng)度小于聲明的長(zhǎng)度,則會(huì)自動(dòng)在該數(shù)據(jù)的右側(cè)用空格補(bǔ)全長(zhǎng)度侥啤;
VARCHAR型數(shù)據(jù)存儲(chǔ)時(shí)当叭,若數(shù)據(jù)長(zhǎng)度小于聲明的長(zhǎng)度,不會(huì)用空格補(bǔ)全盖灸;
以長(zhǎng)度為4的CHAR和VARCHAR舉例:
值 | CHAR(4) | 所需存儲(chǔ)空間 | VARCHAR(4) | 所需存儲(chǔ)空間 |
---|---|---|---|---|
'' |
' ' (存儲(chǔ)了4個(gè)空格) |
4byte | '' |
1byte |
'ab' |
'ab ' (存儲(chǔ)了字符ab及兩個(gè)空格) |
4byte | 'ab' |
3byte |
'abcd' | 'abcd' |
4byte | 'abcd' |
5byte |
'abcdefg' | 'abcd' |
4byte | 'abcd' |
5byte |
是否保留末尾空格
- CHAR型數(shù)據(jù)檢索時(shí)蚁鳖,會(huì)去除數(shù)據(jù)末尾的所有空格
- VARCHAR型數(shù)據(jù)檢索時(shí),會(huì)保留數(shù)據(jù)末尾的所有空格
舉例:
CREATE TABLE varchar_and_char (v VARCHAR(4), c CHAR(4));
INSERT INTO varchar_and_char VALUES ('ab ', 'ab ');
SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM varchar_and_char;
輸出: