MySQL入門教學7 —— 常用資料庫查詢的範例

黄舟
發布: 2017-02-23 11:44:51
原創
1142 人瀏覽過

以下是一些學習如何用MySQL解決一些常見問題的範例。

在一些例子中,使用資料庫表「shop」來儲存某個商人(經銷商)的每件物品(物品號)的價格。假定每個商人對每項物品有一個固定價格,那麼(物品,商人)即為該記錄的主關鍵字。

啟動命令列工具mysql並選擇資料庫:

shell> mysql your-database-name
登入後複製

(在大多數MySQL中,你可以使用test資料庫)。

你可以使用下列語句建立範例表:

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);
登入後複製

執行語句後,表格應包含以下內容:

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. 列的最大值

#「最大的物品號碼是什麼?」

SELECT MAX(article) AS article FROM shop;

+---------+
| article |
+---------+
|       4 |
+---------+
登入後複製

2. 擁有某個欄位的最大值的行

任務:找出最貴物品的編號、銷售商和價格。 這很容易用一個子查詢做到:

SELECT article, dealer, price
FROM   shop
WHERE  price=(SELECT MAX(price) FROM shop);
登入後複製

另一個解決方案是按價格降序排序所有行並用MySQL特定LIMIT子句只得到第一行:

SELECT article, dealer, price
FROM shop
ORDER BY price DESC
LIMIT 1;
登入後複製

附註:如果有多項最貴的物品( 例如每個的價格為19.95),LIMIT解決方案只顯示其中一個!

3. 列的最大值:依組別

任務:每項物品的最高價格是多少?

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. 擁有某個欄位的群組間最大值的行

任務:對每個物品,找出最貴價格的物品的經銷商。

可以用這樣一個子查詢解決這個問題:

SELECT article, dealer, price
FROM   shop s1
WHERE  price=(SELECT MAX(s2.price)
              FROM shop s2
              WHERE s1.article = s2.article);
登入後複製

5. 使用使用者變數

你可以清空MySQL使用者變數以記錄結果,不必將它們儲存到客戶端的臨時變數。

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

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表支援對外部關鍵字約束條件的檢查。

只是聯接兩個表時,不需要外部關鍵字。對於除InnoDB類型的表,當使用REFERENCES tbl_name(col_name)子句定義列時可以使用外部關鍵字,該子句沒有實際的效果,只作為備忘錄或註解來提醒,你目前正定義的欄位指向另一個表格中的一個欄位。 執行該語句時,實作下面很重要:

· MySQL不執行表格tbl_name 中的動作,例如作為你正定義的表中的行的動作的回應而刪除行;換句話說,該語法不會致使ON DELETE或ON UPDATE行為(如果你在REFERENCES子句中寫入ON DELETE或ON UPDATE子句,將被忽略)。

· 該語法可以建立一個column;但不建立任何索引或關鍵字。

· 如果用該句法定義InnoDB表,將會導致錯誤。

你可以使用作為聯結列建立的列,如下所示:

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 &#39;Lilliana%&#39;AND s.owner = p.idAND s.color <> &#39;white&#39;;
+----+-------+--------+-------+| id | style | color  | owner |+----+-------+--------+-------+|  4 | dress | orange |     2 ||  5 | polo  | red    |     2 ||  6 | dress | blue   |     2 |+----+-------+--------+-------+
登入後複製

以這個方式使用,REFERENCES子句不會顯示在SHOW CREATE TABLE或DESCRIBE的輸出:

SHOW CREATE TABLE shirt\G
*************************** 1. row ***************************
Table: shirt
Create Table: CREATE TABLE `shirt` (
`id` smallint(5) unsigned NOT NULL auto_increment,
`style` enum(&#39;t-shirt&#39;,&#39;polo&#39;,&#39;dress&#39;) NOT NULL,
`color` enum(&#39;red&#39;,&#39;blue&#39;,&#39;orange&#39;,&#39;white&#39;,&#39;black&#39;) NOT NULL,
`owner` smallint(5) unsigned NOT NULL,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
登入後複製

在列定義中,以這種方式使用REFERENCES作為註釋或「提示」適用於表MyISAM和BerkeleyDB。

7. 根據兩個鍵搜尋

可以充分利用使用單一關鍵字的OR子句,如同AND的處理。

一個比較靈活的例子是尋找兩個透過OR組合在一起的關鍵字:

SELECT field1_index, field2_index FROM test_table
WHERE field1_index = &#39;1&#39; OR  field2_index = &#39;1&#39;
登入後複製

這個情形是已經最佳化過的。

也可以使用UNION將兩個單獨的SELECT語句的輸出合成在一起來更有效地解決這個問題。

每個SELECT只搜尋一個關鍵字,可以進行最佳化:

SELECT field1_index, field2_index
    FROM test_table WHERE field1_index = &#39;1&#39;
UNION
SELECT field1_index, field2_index
    FROM test_table WHERE field2_index = &#39;1&#39;;
登入後複製

8. 根據天數計算訪問量

下面的例子顯示如何使用位元組函數來計算每個月中使用者造訪網頁的天數。

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);
登入後複製

範例表中含有代表使用者造訪網頁的年-月-日值。可以使用以下查詢來確定每個月的訪問天數:

SELECT year,month,BIT_COUNT(BIT_OR(1<<day)) AS days FROM t1
       GROUP BY year,month;
登入後複製

將返回:

+------+-------+------+
| year | month | days |
+------+-------+------+
| 2000 |    01 |    3 |
| 2000 |    02 |    2 |
+------+-------+------+
登入後複製

該查詢計算了在表中按年/月組合的不同天數,可以自動去除重複的詢問。

9. 使用AUTO_INCREMENT

可以透過AUTO_INCREMENT屬性為新的資料列產生唯一的識別碼:

CREATE TABLE animals (
     id MEDIUMINT NOT NULL AUTO_INCREMENT,
     name CHAR(30) NOT NULL,
     PRIMARY KEY (id)
 );

INSERT INTO animals (name) VALUES
    (&#39;dog&#39;),(&#39;cat&#39;),(&#39;penguin&#39;),
    (&#39;lax&#39;),(&#39;whale&#39;),(&#39;ostrich&#39;);

SELECT * FROM animals;
登入後複製

將回傳:

+----+---------+
| id | name    |
+----+---------+
|  1 | dog     |
|  2 | cat     |
|  3 | penguin |
|  4 | lax     |
|  5 | whale   |
|  6 | ostrich |
+----+---------+
登入後複製

你可以使用LAST_INSERT_ID ()SQL函數或mysql_insert_id() C API函數來查詢最新的AUTO_INCREMENT值。這些函數與特定連接有關,因此其傳回值不會被其它執行插入功能的連接影響。

註解:對於多行插入,LAST_INSERT_ID()和mysql_insert_id()從插入的第一行實際傳回AUTO_INCREMENT關鍵字。在複製設定中,透過該函數可以在其它伺服器上正確複製多行插入。

對於MyISAM和BDB表,你可以在第二欄指定AUTO_INCREMENT以及多列索引。此時,AUTO_INCREMENT列產生的值的計算方法為:MAX(auto_increment_column) + 1 WHERE prefix=given-prefix。如果想要將資料放入到排序的群組中可以使用該方法。

CREATE TABLE animals (
    grp ENUM(&#39;fish&#39;,&#39;mammal&#39;,&#39;bird&#39;) NOT NULL,
    id MEDIUMINT NOT NULL AUTO_INCREMENT,
    name CHAR(30) NOT NULL,
    PRIMARY KEY (grp,id)
);

INSERT INTO animals (grp,name) VALUES
    (&#39;mammal&#39;,&#39;dog&#39;),(&#39;mammal&#39;,&#39;cat&#39;),
    (&#39;bird&#39;,&#39;penguin&#39;),(&#39;fish&#39;,&#39;lax&#39;),(&#39;mammal&#39;,&#39;whale&#39;),
    (&#39;bird&#39;,&#39;ostrich&#39;);

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 |
+--------+----+---------+
登入後複製

请注意在这种情况下(AUTO_INCREMENT列是多列索引的一部分),如果你在任何组中删除有最大AUTO_INCREMENT值的行,将会重新用到AUTO_INCREMENT值。对于MyISAM表也如此,对于该表一般不重复使用AUTO_INCREMENT值。

如果AUTO_INCREMENT列是多索引的一部分,MySQL将使用该索引生成以AUTO_INCREMENT列开始的序列值。。例如,如果animals表含有索引PRIMARY KEY (grp, id)和INDEX(id),MySQL生成序列值时将忽略PRIMARY KEY。结果是,该表包含一个单个的序列,而不是符合grp值的序列。

要想以AUTO_INCREMENT值开始而不是1,你可以通过CREATE TABLE或ALTER TABLE来设置该值,如下所示:

mysql> ALTER TABLE tbl AUTO_INCREMENT = 100;
登入後複製

 以上就是MySQL入门教程7 —— 常用数据库查询的示例的内容,更多相关内容请关注PHP中文网(www.php.cn)! 




相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!