MySQL必知必會(2):數據檢索(SELECT)

本文介紹Mysql開發中使用最頻繁的功能,SELECT數據檢索mysql

簡介

檢索數據是從數據庫中使用特定語句獲取頁面須要的數據。天天你上網瀏覽的網頁,絕大部分數據都是從數據庫中檢索出來,因此它也是mysql最經常使用的功能之一。sql

從Mysql檢索數據至少須要提供兩個信息:數據庫

  1. 你須要查找什麼segmentfault

  2. 你須要從哪一個表中查詢函數

檢索數據

單列檢索

咱們有了上面兩個兩個信息,咱們就能夠組合成爲一個最基本的查詢語句:工具

SELECT name FROM my_user;

上面語句咱們從my_user表查詢了用戶的名字。性能

由此咱們能夠看出,最基本的查詢語句是由SELECT和FROM關鍵字組成。SELECT後面跟着你須要查詢的字段,FROM後面跟着你須要從哪一個表查詢出這些數據。spa

圖片描述

上圖的數據庫表能夠從本文最後附錄獲取。因爲尚未講解到數據排序,因此你檢索出來的數據順序和個人不同也不要驚訝。命令行

幾個點說明:3d

  1. 若是在命令行執行SQL語句,那麼須要使用分號結尾。

  2. 其餘的狀況下,Mysql不要求必定加上分號結尾,可是咱們建議加上分號結尾。

  3. Mysql不區分大小寫,實際開發中習慣將關鍵字大寫,其餘小寫。好比SELECT、FROM

  4. 部分版本的Mysql中(好比4.1及以前的版本)數據庫名、表名、字段名區分大小寫。建議養成大小寫一致的習慣。

  5. Mysql默認會將多個空格合併成一個空格,因此爲了便於閱讀,通常會將較長SQL語句換行書寫

多列檢索

多列檢索相似於上面一個例子,只不過查詢的字段變成了多個。多個字段之間使用英文逗號分隔:

SELECT name,age,code FROM my_user;

這一次咱們檢索了3個字段。記住,只能是字段之間使用逗號分隔,最後一個字段(這裏是code)以後不能有逗號,不然Mysql會報錯。

圖片描述

檢索所有字段

除了一個個的寫出須要檢索的字段外,Mysql還提供了一個星號*表明檢索全部字段:

SELECT * FROM my_user;

圖片描述

能夠看到所有的字段信息都被檢索了出來,少寫了很多單詞。這種方法十分簡單,並且能夠檢索出數據庫中你可能不知道存在的字段,在某些狀況下十分有用。

可是,開發中建議不要使用這種方式檢索。緣由就是會致使數據庫檢索性能降低。因爲,檢索出來的全部數據都會放在內存。因此,當你只須要好比文章標題時候,你也檢索出文章內容。內存就會被文章內容嚴重消耗。

咱們建議,須要什麼字段就檢索什麼字段,少用星號檢索所有字段。

去除重複記錄

以前使用的例子中共有5個用戶,其中25歲的用戶有兩個,小黃和小穎。假設咱們如今只想看看用戶的年齡層次,每一個年齡只能出現一次。

按照以前方法查詢

SELECT age FROM my_user;

咱們會獲得5條記錄,2次出現25.可是咱們並不須要重複的25.Mysql提供了一個去除重複記錄的關鍵字DISTINCT,只要將它加在檢索的字段前面,便可去除重複記錄。

SELECT DISTINCT age FROM my_user;

圖片描述

上圖結果中25只出現了一次。可是這種方法只能用在一個字段時候,若是咱們添加一個查詢字段name那麼,依然會顯示全部的結果。

SELECT DISTINCT age,`name` FROM my_user;

圖片描述

LIMIT限制記錄數量

數據庫是能夠存放千萬條數據的地方,可是咱們每次檢索不可能將這麼多數據。好比咱們只須要前20條,或者須要第10條到第30條數據。這時,就須要LIMIT關鍵字做檢索記錄條數限制。

SELECT age,`name` FROM my_user LIMIT 2;

圖片描述

上面例子中,咱們在以前SQL語句後面添加了一個LIMIT 2,檢索出來的記錄數量由5條變爲了2條。

咱們更改一下LIMIT後面的數值

SELECT age,`name` FROM my_user LIMIT 10;

圖片描述

這一次咱們改成了10,而咱們只有5條記錄,因此只顯示了5條。因而可知,LIMIT後面的數字表明的是不超過數值的記錄數。

其實上面的寫法是一種簡寫,LIMIT後面正常是2個數字。

SELECT age,`name` FROM my_user LIMIT 0,2;

圖片描述

咱們將上面的例子填寫完整,發現結果徹底同樣。

說明:

  1. LIMIT後面的第一個數字爲從第幾條開始檢索。第一條爲0,搞開發的都知道。

  2. LIMIT後面第二個數字爲本次檢索記錄的條數。

  3. 當從首行記錄開始檢索時候,能夠省略第一個數字,只寫一個記錄數。

代碼寫多了,你就會發現LIMIT n,m這種狀況特別容易混淆兩個數字的含義。因此,在Mysql 5版本以後,支持另一種更爲清晰的寫法:

LIMIT 4 OFFSET 3 // 表示從行3處取4行數據,至關於LIMIT 3,4

數據排序

數據排序在數據檢索中很是經常使用。打個比方,你寫博客,在數據庫中插入的順序是最早寫的在最後一行。可是咱們想獲得的列表是,最早寫的排在第一行,這樣咱們就須要將列表倒過來,也就是倒序。固然還有正序。

單字段排序

排序,使用關鍵字ORDER BY。可是,這裏必需要有一個參照的關鍵字,好比你想文章按照寫的順序倒序。你能夠按照文章建立時間倒序,時間大的在前。這裏的時間就被成爲排序依照字段。

咱們沒有文章表,仍是拿上面的例子:

SELECT age,`name` FROM my_user ORDER BY age DESC

這條語句的意思是將用戶按照年齡從大到小的順序檢索出來。

圖片描述

咱們看下結果,較上面結果發生了順序變化,年齡從大到小。其中的age就是排序的依照字段,最後一個關鍵字DESC表示他前面的age按照倒序排列。

正序排列就是ORDER BY age ASC,其中默認就是ASC,因此能夠不寫。

多字段排序

上面例子檢索出來結果咱們看到,在前面有兩個25歲的用戶。他們年齡都是25,可是我如今想讓小穎在第一個。這裏就涉及到了多字段排序。

多字段排序也就是屢次排序,其中第一個字段優先級最高,若是第一個字段出現重複,則使用第二個字段排序。

SELECT user_id,age,`name` FROM my_user ORDER BY age DESC,user_id DESC

這一次咱們添加了一個排序字段user_id,而且使用倒序。爲了顯示清楚,咱們把user_id字段也檢索出來。此次發現小穎被排到了第一個。

Mysql執行的流程是:首先使用age排序,可是發現小黃和小穎age重複,因此使用第二個字段繼續排序。第二個字段爲user_id DESC因此user_id比較大的被排到了前面。

注意

  1. ORDER BY 後面的關鍵字DESC或者ASC必須跟在每個字段後面,來表示當前字段的排序。

  2. 在Mysql的默認行爲中,文本a和A開頭的字符具備相同的排序優先級。可是也能夠經過數據庫設置來修改該行爲。

  3. 若是在須要使用LIMIT的語句中也使用了ORDER BY關鍵字,那麼LIMIT應該放在ORDER BY以後,不然數據庫會報錯。

條件檢索

數據庫通常都包含大量數據,可是每每咱們都不須要一次檢索出所有,也不會說只用LIMIT來限制。咱們一般會有針對性的篩選須要的數據,好比年齡爲25歲的全部用戶。這時候就須要WHERE篩選數據,給出的搜索條件也被稱爲過濾條件。

WHERE子句

在Mysql,咱們能夠在FROM關鍵字以後給出WHERE關鍵字來篩選數據:

SELECT * FROM my_user WHERE age=25;

這條SQL咱們檢索出了全部年齡爲25歲的用戶。咱們使用了age=25,固然Mysql還能夠執行更多的功能,好比大於、小於等等,看下面一個知識點。

注意:若是在SQL語句中須要使用WHERE和ORDER BY,請將ORDER BY放到WHERE以後,不然會報錯

操做符

上面咱們僅僅演示了age=25的狀況,其實Mysql還支持更多的操做符(上個例子中的=號就是操做符)

操做符 說明
= 等於
<> 不等於
!= 不等於
< 小於
<= 小於等於
> 大於
>= 大於等於
BETWEEN 指定的兩個值之間

下面咱們拿以前的用戶表演示一下

全部數據

SELECT * FROM my_user;

圖片描述

不等於

SELECT * FROM my_user WHERE age <> 25;
SELECT * FROM my_user WHERE age != 25; // 這兩個結果同樣

圖片描述

小於

此次咱們改成了小於20

SELECT * FROM my_user WHERE age < 20;

圖片描述

小於等於

SELECT * FROM my_user WHERE age <= 20;

圖片描述

大於

SELECT * FROM my_user WHERE age > 20;

圖片描述

大於等於

SELECT * FROM my_user WHERE age >= 20;

圖片描述

BETWEEN

SELECT * FROM my_user WHERE age BETWEEN 19 AND 22;

圖片描述

  1. BETWEEN關鍵字後面須要跟上2個數值,表示一個範圍,兩個數值之間使用AND分割。

  2. BETWEEN後面的兩個數值檢索出來的範圍包含這兩個數值。好比咱們BETWEEN 19 AND 22就是1九、20、2一、22均可以

組合查詢

上面的例子中,咱們WHERE後面值跟了一個條件。其實,WHERE後面容許跟隨多個條件,他們容許用AND或者OR進行鏈接。

AND

and表示而且的關係。

SELECT * FROM my_user WHERE age = 25 AND user_id = 4;

上面的例子中咱們使用and鏈接了兩個條件age=25user_id=4。它的意思是年齡爲25歲的用戶,而且用戶ID爲4的用戶。

以前咱們查詢age=25的時候有兩條記錄,可是咱們and了一個條件,結果變爲了一個。因此,and是縮小範圍。

OR

or表示或者的關係。

SELECT * FROM my_user WHERE age = 25 OR user_id = 1;

圖片描述

此次咱們查詢年齡爲25歲,或者用戶ID爲1的用戶。因此年齡爲25歲,或者用戶ID等於1的用戶都會被檢索出來,哪怕年齡不爲25歲。

因此能夠看出or關鍵字連接的語句,可能會放大查詢的範圍。

計算優先級

首先查看一個例子

SELECT * FROM my_user WHERE age = 25 OR user_id = 1 AND user_id > 3;

按照正常的思惟理解,咱們先獲取到了年齡等於25歲的,或者用戶ID爲1的用戶:

咱們應該獲得以下結果:

圖片描述

再加上用戶ID大於3的條件,咱們應該獲得用戶ID爲4的用戶小穎的信息。而,實際操做中咱們發現結果並非一條,而是兩條:

圖片描述

咱們再次使用括號將前面兩個條件括起來,執行一次:

SELECT * FROM my_user WHERE (age = 25 OR user_id = 1) AND user_id > 3;

圖片描述

獲得了咱們想要的答案(儘管沒啥意義)。

第一條語句產生錯誤的結果是優先級不一樣。AND的優先級高於OR優先級。因此第一條語句中Mysql是先計算了user_id = 1 AND user_id > 3這個條件沒有獲得任何的數據。加上後面的or age =25.因此最後結果就只剩下年齡爲25歲的用戶記錄了。

因此,在實際開發中,遇到OR和AND並存的狀況必定要注意是否會應爲優先級影響結果。使用圓括號能夠改變Mysql計算的優先級,必定要慎重。

IN

IN關鍵字很是有意思。他包含一個括號,像一個函數。在括號裏面你能夠寫上使用逗號分割的數值,只要數值與括號內的匹配,那麼就符合條件。

SELECT * FROM my_user WHERE age IN(25,20);

圖片描述

咱們使用上面的語句檢索出了年齡等於20或者25歲的用戶。並且IN還能夠和OR關鍵字互相替換。好比上面的IN語句能夠轉換爲:

SELECT * FROM my_user WHERE age =20 OR age =25;

可是爲啥仍是要用IN:

  1. IN操做符的語法更加簡潔,SQL語句長度縮短,不容易出錯。

  2. 計算的優先級更加容易看出,不用考慮OR和AND那些關係

  3. IN操做符執行速度快於OR

  4. IN還能夠結合子查詢使用,動態的生成查詢值(後續文章中會說到子查詢)

NOT

not操做符就只有一個功能,否認後面跟的條件。

SELECT * FROM my_user WHERE age NOT IN(20,25);

圖片描述

結果是否是和剛剛反了過來。

附錄

建立my_user表的語句:

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for my_user
-- ----------------------------
DROP TABLE IF EXISTS `my_user`;
CREATE TABLE `my_user` (
  `user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL,
  `age` tinyint(2) NOT NULL DEFAULT '0',
  `password` varchar(40) NOT NULL,
  `code` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of my_user
-- ----------------------------
INSERT INTO `my_user` VALUES ('1', '小紅', '20', '7c4a8d09ca3762af61e59520943dc26494f8941b', '2arfs5dr6m');
INSERT INTO `my_user` VALUES ('2', '小明', '19', '7c4a8d09ca3762af61e59520943dc26494f8941b', 'd59tg6dr5h');
INSERT INTO `my_user` VALUES ('3', '小黃', '25', '7c4a8d09ca3762af61e59520943dc26494f8941b', 'w56tg9hjn3');
INSERT INTO `my_user` VALUES ('4', '小穎', '25', '7c4a8d09ca3762af61e59520943dc26494f8941b', 'a5d23e9yh5');
INSERT INTO `my_user` VALUES ('5', '星空幻穎', '22', '7c4a8d09ca3762af61e59520943dc26494f8941b', '86d2sadft9');

圖片所示的軟件工具是navicat,更多的 數據庫管理軟件,百度:筆點資源:發現更多開發乾貨集合資源

圖片描述

星空幻穎,嚴穎

我的主頁:segmentfault

相關文章
相關標籤/搜索