MySQL入門(mén)教程7 —— 常用數(shù)據(jù)庫(kù)查詢的示例

下面是一些學(xué)習(xí)如何用mysql解決一些常見(jiàn)問(wèn)題的例子。

在一些例子中,使用數(shù)據(jù)庫(kù)表“shop”來(lái)儲(chǔ)存某個(gè)商人(經(jīng)銷(xiāo)商)的每件物品(物品號(hào))的價(jià)格。假定每個(gè)商人對(duì)每項(xiàng)物品有一個(gè)固定價(jià)格,那么(物品,商人)即為該記錄的主關(guān)鍵字。

啟動(dòng)命令行工具mysql并選擇數(shù)據(jù)庫(kù):

shell>?mysql?your-database-name

(在大多數(shù)MySQL中,你可以使用test數(shù)據(jù)庫(kù))。

你可以使用以下語(yǔ)句創(chuàng)建示例表:

mysql>?CREATE?TABLE?shop?(?????->?article?INT(4)?UNSIGNED?ZEROFILL?DEFAULT?'0000'?NOT?NULL,?????->?dealer??CHAR(20)?????????????????DEFAULT?''?????NOT?NULL,?????->?price???DOUBLE(16,2)?????????????DEFAULT?'0.00'?NOT?NULL,?????->?PRIMARY?KEY(article,?dealer));?mysql>?INSERT?INTO?shop?VALUES?????->?(1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),?????->?(3,'C',1.69),(3,'D',1.25),(4,'D',19.95);

執(zhí)行語(yǔ)句后,表應(yīng)包含以下內(nèi)容:

mysql>?SELECT?*?FROM?shop;?+---------+--------+-------+  |?article?|?dealer?|?price?|  +---------+--------+-------+  |????0001?|?A??????|??3.45?|  |????0001?|?B??????|??3.99?|  |????0002?|?A??????|?10.99?|  |????0003?|?B??????|??1.45?|  |????0003?|?C??????|??1.69?|  |????0003?|?D??????|??1.25?|  |????0004?|?D??????|?19.95?|  +---------+--------+-------+

1.?列的最大值

“最大的物品號(hào)是什么?”

SELECT?MAX(article)?AS?article?FROM?shop;    +---------+  |?article?|  +---------+  |???????4?|  +---------+

2.?擁有某個(gè)列的最大值的行

任務(wù):找出最貴物品的編號(hào)、銷(xiāo)售商和價(jià)格。這很容易用一個(gè)子查詢做到:

SELECT?article,?dealer,?price  FROM???shop  WHERE??price=(SELECT?MAX(price)?FROM?shop);

另一個(gè)解決方案是按價(jià)格降序排序所有行并用MySQL特定LIMIT子句只得到第一行:

SELECT?article,?dealer,?price  FROM?shop  ORDER?BY?price?DESC  LIMIT?1;

:如果有多項(xiàng)最貴的物品(?例如每個(gè)的價(jià)格為19.95),LIMIT解決方案僅僅顯示其中一個(gè)!

3.?列的最大值:按組

任務(wù):每項(xiàng)物品的的最高價(jià)格是多少?

SELECT?article,?MAX(price)?AS?price  FROM???shop  GROUP?BY?article    +---------+-------+  |?article?|?price?|  +---------+-------+  |????0001?|??3.99?|  |????0002?|?10.99?|  |????0003?|??1.69?|  |????0004?|?19.95?|  +---------+-------+

4.?擁有某個(gè)字段的組間最大值的行

任務(wù):對(duì)每項(xiàng)物品,找出最貴價(jià)格的物品的經(jīng)銷(xiāo)商。

可以用這樣一個(gè)子查詢解決該問(wèn)題:

SELECT?article,?dealer,?price  FROM???shop?s1  WHERE??price=(SELECT?MAX(s2.price)  ??????????????FROM?shop?s2  ??????????????WHERE?s1.article?=?s2.article);

5.?使用用戶變量

你可以清空MySQL用戶變量以記錄結(jié)果,不必將它們保存到客戶端的臨時(shí)變量中。

例如,要找出價(jià)格最高或最低的物品的,其方法是:

mysql>?SELECT?@min_price:=MIN(price),@max_price:=MAX(price)?FROM?shop;?mysql>?SELECT?*?FROM?shop?WHERE?price=@min_price?OR?price=@max_price;?+---------+--------+-------+  |?article?|?dealer?|?price?|  +---------+--------+-------+  |????0003?|?D??????|??1.25?|  |????0004?|?D??????|?19.95?|  +---------+--------+-------+

6.?使用外鍵

在MySQL中,InnoDB表支持對(duì)外部關(guān)鍵字約束條件的檢查。

只是聯(lián)接兩個(gè)表時(shí),不需要外部關(guān)鍵字。對(duì)于除InnoDB類(lèi)型的表,當(dāng)使用REFERENCES?tbl_name(col_name)子句定義列時(shí)可以使用外部關(guān)鍵字,該子句沒(méi)有實(shí)際的效果,只作為備忘錄或注釋來(lái)提醒,你目前正定義的列指向另一個(gè)表中的一個(gè)列。執(zhí)行該語(yǔ)句時(shí),實(shí)現(xiàn)下面很重要:

·?MySQL不執(zhí)行表tbl_name?中的動(dòng)作,例如作為你正定義的表中的行的動(dòng)作的響應(yīng)而刪除行;換句話說(shuō),該句法不會(huì)致使ON DELETE或ON UPDATE行為(如果你在REFERENCES子句中寫(xiě)入ON DELETE或ON UPDATE子句,將被忽略)。

·?該句法可以創(chuàng)建一個(gè)column;但不創(chuàng)建任何索引或關(guān)鍵字。

·?如果用該句法定義InnoDB表,將會(huì)導(dǎo)致錯(cuò)誤。

你可以使用作為聯(lián)接列創(chuàng)建的列,如下所示:

CREATE?TABLE?person?(  ????id?SMALLINT?UNSIGNED?NOT?NULL?AUTO_INCREMENT,  ????name?CHAR(60)?NOT?NULL,  ????PRIMARY?KEY?(id)  );    CREATE?TABLE?shirt?(  ????id?SMALLINT?UNSIGNED?NOT?NULL?AUTO_INCREMENT,  ????style?ENUM('t-shirt',?'polo',?'dress')?NOT?NULL,  ????color?ENUM('red',?'blue',?'orange',?'white',?'black')?NOT?NULL,  ????owner?SMALLINT?UNSIGNED?NOT?NULL?REFERENCES?person(id),  ????PRIMARY?KEY?(id)  );    INSERT?INTO?person?VALUES?(NULL,?'Antonio?Paz');    SELECT?@last?:=?LAST_INSERT_ID();    INSERT?INTO?shirt?VALUES  (NULL,?'polo',?'blue',?@last),  (NULL,?'dress',?'white',?@last),  (NULL,?'t-shirt',?'blue',?@last);    INSERT?INTO?person?VALUES?(NULL,?'Lilliana?Angelovska');    SELECT?@last?:=?LAST_INSERT_ID();    INSERT?INTO?shirt?VALUES  (NULL,?'dress',?'orange',?@last),  (NULL,?'polo',?'red',?@last),  (NULL,?'dress',?'blue',?@last),  (NULL,?'t-shirt',?'white',?@last);    SELECT?*?FROM?person;  +----+---------------------+  |?id?|?name????????????????|  +----+---------------------+  |??1?|?Antonio?Paz?????????|  |??2?|?Lilliana?Angelovska?|  +----+---------------------+    SELECT?*?FROM?shirt;
+----+---------+--------+-------+|?id?|?style???|?color??|?owner?|+----+---------+--------+-------+|??1?|?polo????|?blue???|?????1?||??2?|?dress???|?white??|?????1?||??3?|?t-shirt?|?blue???|?????1?||??4?|?dress???|?orange?|?????2?||??5?|?polo????|?red????|?????2?||??6?|?dress???|?blue???|?????2?||??7?|?t-shirt?|?white??|?????2?|+----+---------+--------+-------+  SELECT?s.*?FROM?person?p,?shirt?sWHERE?p.name?LIKE?'Lilliana%'AND?s.owner?=?p.idAND?s.color??'white';  +----+-------+--------+-------+|?id?|?style?|?color??|?owner?|+----+-------+--------+-------+|??4?|?dress?|?orange?|?????2?||??5?|?polo??|?red????|?????2?||??6?|?dress?|?blue???|?????2?|+----+-------+--------+-------+

按照這種方式使用,REFERENCES子句不會(huì)顯示在SHOW CREATE TABLE或DESCRIBE的輸出中:

SHOW?CREATE?TABLE?shirtG  ***************************?1.?row?***************************  Table:?shirt  Create?Table:?CREATE?TABLE?`shirt`?(  `id`?smallint(5)?unsigned?NOT?NULL?auto_increment,  `style`?enum('t-shirt','polo','dress')?NOT?NULL,  `color`?enum('red','blue','orange','white','black')?NOT?NULL,  `owner`?smallint(5)?unsigned?NOT?NULL,  PRIMARY?KEY??(`id`)  )?ENGINE=MyISAM?DEFAULT?CHARSET=latin1

在列定義中,按這種方式使用REFERENCES作為注釋或“提示”適用于表MyISAM和BerkeleyDB。

7.?根據(jù)兩個(gè)鍵搜索

可以充分利用使用單關(guān)鍵字的OR子句,如同AND的處理。

一個(gè)比較靈活的例子是尋找兩個(gè)通過(guò)OR組合到一起的關(guān)鍵字:

SELECT?field1_index,?field2_index?FROM?test_table  WHERE?field1_index?=?'1'?OR??field2_index?=?'1'

該情形是已經(jīng)優(yōu)化過(guò)的。

還可以使用UNION將兩個(gè)單獨(dú)的SELECT語(yǔ)句的輸出合成到一起來(lái)更有效地解決該問(wèn)題。

每個(gè)SELECT只搜索一個(gè)關(guān)鍵字,可以進(jìn)行優(yōu)化:

SELECT?field1_index,?field2_index  ????FROM?test_table?WHERE?field1_index?=?'1'  UNION  SELECT?field1_index,?field2_index  ????FROM?test_table?WHERE?field2_index?=?'1';

8.?根據(jù)天計(jì)算訪問(wèn)量

下面的例子顯示了如何使用位組函數(shù)來(lái)計(jì)算每個(gè)月中用戶訪問(wèn)網(wǎng)頁(yè)的天數(shù)。

CREATE?TABLE?t1?(year?YEAR(4),?month?INT(2)?UNSIGNED?ZEROFILL,  ?????????????day?INT(2)?UNSIGNED?ZEROFILL);  INSERT?INTO?t1?VALUES(2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2),  ????????????(2000,2,23),(2000,2,23);

示例表中含有代表用戶訪問(wèn)網(wǎng)頁(yè)的年-月-日值??梢允褂靡韵虏樵儊?lái)確定每個(gè)月的訪問(wèn)天數(shù):

SELECT?year,month,BIT_COUNT(BIT_OR(1<p>將返回:</p><pre class="brush:php;toolbar:false;">+------+-------+------+  |?year?|?month?|?days?|  +------+-------+------+  |?2000?|????01?|????3?|  |?2000?|????02?|????2?|  +------+-------+------+

該查詢計(jì)算了在表中按年/月組合的不同天數(shù),可以自動(dòng)去除重復(fù)的詢問(wèn)。

9.?使用AUTO_INCREMENT

可以通過(guò)AUTO_INCREMENT屬性為新的行產(chǎn)生唯一的標(biāo)識(shí):

CREATE?TABLE?animals?(  ?????id?MEDIUMINT?NOT?NULL?AUTO_INCREMENT,  ?????name?CHAR(30)?NOT?NULL,  ?????PRIMARY?KEY?(id)  ?);    INSERT?INTO?animals?(name)?VALUES  ????('dog'),('cat'),('penguin'),  ????('lax'),('whale'),('ostrich');    SELECT?*?FROM?animals;

將返回:

+----+---------+  |?id?|?name????|  +----+---------+  |??1?|?dog?????|  |??2?|?cat?????|  |??3?|?penguin?|  |??4?|?lax?????|  |??5?|?whale???|  |??6?|?ostrich?|  +----+---------+

你可以使用LAST_INSERT_ID()SQL函數(shù)或mysql_insert_id()?C API函數(shù)來(lái)查詢最新的AUTO_INCREMENT值。這些函數(shù)與具體連接有關(guān),因此其返回值不會(huì)被其它執(zhí)行插入功能的連接影響。

注釋:對(duì)于多行插入,LAST_INSERT_ID()和mysql_insert_id()從插入的第一行實(shí)際返回AUTO_INCREMENT關(guān)鍵字。在復(fù)制設(shè)置中,通過(guò)該函數(shù)可以在其它服務(wù)器上正確復(fù)制多行插入。

對(duì)于MyISAM和BDB表,你可以在第二欄指定AUTO_INCREMENT以及多列索引。此時(shí),AUTO_INCREMENT列生成的值的計(jì)算方法為:MAX(auto_increment_column) + 1 WHERE prefix=given-prefix。如果想要將數(shù)據(jù)放入到排序的組中可以使用該方法。

CREATE?TABLE?animals?(  ????grp?ENUM('fish','mammal','bird')?NOT?NULL,  ????id?MEDIUMINT?NOT?NULL?AUTO_INCREMENT,  ????name?CHAR(30)?NOT?NULL,  ????PRIMARY?KEY?(grp,id)  );    INSERT?INTO?animals?(grp,name)?VALUES  ????('mammal','dog'),('mammal','cat'),  ????('bird','penguin'),('fish','lax'),('mammal','whale'),  ????('bird','ostrich');    SELECT?*?FROM?animals?ORDER?BY?grp,id;

將返回:

+--------+----+---------+  |?grp????|?id?|?name????|  +--------+----+---------+  |?fish???|??1?|?lax?????|  |?mammal?|??1?|?dog?????|  |?mammal?|??2?|?cat?????|  |?mammal?|??3?|?whale???|  |?bird???|??1?|?penguin?|  |?bird???|??2?|?ostrich?|  +--------+----+---------+

請(qǐng)注意在這種情況下(AUTO_INCREMENT列是多列索引的一部分),如果你在任何組中刪除有最大AUTO_INCREMENT值的行,將會(huì)重新用到AUTO_INCREMENT值。對(duì)于MyISAM表也如此,對(duì)于該表一般不重復(fù)使用AUTO_INCREMENT值。

如果AUTO_INCREMENT列是多索引的一部分,MySQL將使用該索引生成以AUTO_INCREMENT列開(kāi)始的序列值。。例如,如果animals表含有索引PRIMARY KEY (grp, id)和INDEX(id),MySQL生成序列值時(shí)將忽略PRIMARY KEY。結(jié)果是,該表包含一個(gè)單個(gè)的序列,而不是符合grp值的序列。

要想以AUTO_INCREMENT值開(kāi)始而不是1,你可以通過(guò)CREATE TABLE或ALTER TABLE來(lái)設(shè)置該值,如下所示:

mysql&gt;?ALTER?TABLE?tbl?AUTO_INCREMENT?=?100;

?以上就是MySQL入門(mén)教程7 —— 常用數(shù)據(jù)庫(kù)查詢的示例的內(nèi)容,更多相關(guān)內(nèi)容請(qǐng)關(guān)注PHP中文網(wǎng)(www.php.cn)!?

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊11 分享