資料表都已經建立起來了,假設我們已經插入了許多的資料,我們就可以用自己喜歡的方式對資料表裡面的資訊進行檢索和顯示了,比如說:可以象下面這樣把整個資料表內的內容都顯示出來
select * from president;
也可以只選取某一個資料行裡的某一個資料列
select birth from president where last_name=’Eisenhower’;
select語句的通用形式如下:
select 你要的資訊
from 資料表(一個或多個)
where 滿足的條件
select語句有幾個子句,他們的各種搭配能幫你查出最感興趣的資訊,這些子句可以很簡單,也可以很複雜,看看作者是如何詳細講解的
1, 用各種操作符來設定檢索條件
要想讓select語句只把滿足特定條件的記錄檢索出來,就必須給它加上where字句來設定資料行的檢索條件。只有這樣,才能有選擇地把資料列的取值滿足特定要求的那些資料行挑選出來。可以針對任何類型的值進行尋找,比如說,對數值進行搜尋
select * from score where score>95; //顯示所有分數在95分以上的資訊
也可以針對字串值進行尋找
select last_name,first_name from president where last_name=’Tom’; //找出所有姓tom的總統
還可以對不同類型的值進行組合尋找
select last_name,first_name,birth,state from president
where birth<’1950-1-1’ and (state=’VA’ or state=’BA’);
//找出1950年前出生於VA州或BA州的總統
可見 where子句中可以使用的是算術操作符(+-*/%),比較操作符(<>=)以及邏輯運算子,我們應該熟練理解這些操作符的含義(都很簡單)
2, NULL 值的特別處理
這是一種不屬於任何類型的值。它通常用來表示“沒有資料”“資料未知”“資料缺失”“資料超出取值範圍”“與本資料列無關”“與本資料列的其它值不同”等多種含義。在許多情況下,NULL 值是非常有用的。
我們的各種操作符是不能對NULL 值進行處理的,如果相對NULL 值進行尋找,用的是 is null 或 is not null 來進行判斷,舉例如下:
select last_name,first_name,birth,state from president
where death is null; //找出所有沒死的總統
在某些情況下,NULL 值是很有用的類型,大家慢慢就會理解的。
3, 查詢結果進行排序
一般說來,如果建立了一個資料表並向裡面插入了一些記錄,當發出一條select * from name命令的時候,資料記錄在查詢結果中的先後順序通常與它們被插入時的先後順序一樣.這當然符合我們的思維習慣.但這隻是一種"想當然"的假設而已,事實上,但記錄被刪除時,資料庫中會產生一些空的地區,MYSQL會用新的記錄來填補這些地區,也就是說,這個時候本假設就不正確了.因此我們必須記住一點,從伺服器返回的記錄行的先後順序是沒有任何保證的!如果想要按照一定的順序,就必須使用order by 子句來設定這個順序.
select last_name,first_name,birth,state from president
order by last_name; //讓總統們的名字按字母順序排列
還可以設定排列的升序降序
select last_name,first_name from president
order by state DESC,last_name ASC;
//先按照出生地的降序排列,同出生地的按照姓氏的升序排列
注意:如果結果中含有NULL 值,預設情況下他們總是出現在查詢結果的開頭。
4, 限制查詢結果中資料行個數
這個簡單,只要用limit 子句就可以了,看兩個例子:
select last_name,first_name,birth,state from president
order by birth limit 5; //只想看前5個
order by birth limit 10,5; //返回從第11個記錄開始的5個記錄(跳過了10個)
小技巧:從president表中隨機找出一個總統來玩:
select last_name,first_name,birth,state from president
order by rand() limit 1; //這是用了運算式求值的方法,在哪裡都管用
5, 對輸出資料行進行求值和命名
為了提高效率,MYSQL還可以把運算式的計算結果當作輸出資料行的值。運算式可以很簡單,也可以很複雜。例如:下面這個查詢有兩個輸出資料行,前一個輸出資料行對應一個非常簡單的運算式(一個常數),而後一個輸出資料行則對應著一個使用了多個算術運算子和兩個函數調用的複雜運算式。
Select 17,format(sqrt(3*3+4*4),0))
輸出:17 5
再看這個命令:把兩個輸出資料行合并成一個
select concat(first_namem,’ ‘,last_name),concat(city,’,’,state) from president;
如果合并之後輸出資料行的標題過長,則可以給其一個別名,如:
select concat(first_namem,’ ‘,last_name) as name,
concat(city,’,’,state) as birth place
from president;這樣就比較美觀了。
6, 和日期有關的問題
首先記住:在MYSQL中,年份是放到最前面的!我們通常對日期進行下列操作:
按日期進行排序
尋找某個日期或日期範圍
提取日期中的年,元,日各個部分
計算兩個日期的間隔
用一個日期求出另外一個日期
看例子:
select * from event where date=’2002-10-01’ //看看這天有何考試資訊?
select last_name,first_name,birth,state from president
where death>’1900-01-01’ and death<’2000-01-01’; //看看上個世紀死了幾個?
三個函數year,month,dayofmonth可以分別分離出日期中的年月日來。
select last_name,first_name,birth from president
where month(birth)=3; //誰生在3月 ?
where month(birth)=7 and dayofmonth(birth) =6; //誰生在7月6日?(湯姆克魯斯?)
函數to_days可以把日期轉換為天數。
select last_name,first_name,birth to_days(death)-to_days(birth) as age from president
可以看看這幫傢伙都活了多少天!你自己把它改為年吧。
日期值的減法運算還能幫我們計算出現在距離某個特定日期還有多長的時間,這正是我們用來找到需要在近期內繳納會費的會員的辦法:
select last_name,first_name,expiration from member
where (to_days(expiration)-to_days(curdate())<60; //有些人60天內需要花錢了!
7, 模式比對
有些情況下,模糊查詢是很必要的,我們使用like和not like加上一個帶萬用字元的字串就可以了。共有兩個萬用字元”_”(單個字元)和”%”(任意個字元,包括0個)
select concat(first_namem,’ ‘,last_name) as name,
where last_name like ‘W%’; //找到以W或w開頭的人
where last_name like ‘%W%’; //找到名字裡面W或w開頭的人
8, 設定和使用SQL變數
MYSQL 3.23.6以上的版本可以使用查詢結果來設定變數,我們就能夠方面的把一些結果儲存起來以供他用。變數的命名規格是:@name, 賦值文法是 @name:=value ( pascal?) 使用起來也簡單:
select @birth:=birth from president
where last_name =’adsltiger’; //執行完成後我們就就會有一個@birth變數可用
用一下試試:
select concat(first_namem,’ ‘,last_name) as name from president
where birth<@birth order by birth; //看看那些人比我大!
*9, 產生統計資訊
單純依靠手工來產生統計資訊是一項既艱苦又耗時還容易出錯的工作,如果我們能熟練掌握用資料庫來產生各種統計資訊的技巧,他就會成為很有威力的資訊處理工具。作者在這裡用了許多篇幅講這個主題,為了便於大家理解,我分解開來論述:
9.1 找出一組資料中到底有多少種不同的值是一項比較常見的統計工作,而關鍵字distinct就可以把查詢結果中的重複資料清除掉。如
select distinct state from president //看看美國總統們都來自那些州?(重複的不計)
9.2用count()函數來統計相關記錄的個數,注意其使用方法:count(*)計算所有的,NULL也要;count(資料列名稱) NULL值不計算在內。
select count(*) from president;
9.3如果我們想知道班級內的男女生數目?該如何查詢呢?最簡單的方法是
select count(*) from student where sex=’f’;
select count(*) from student where sex=’m
但是如果使用count函數結合group by關鍵字,一行命令就搞定了
select sex,count(*) f rom student group by sex;
我們可以看到,與反覆使用彼此類似的查詢來分別統計某資料列不同取值出現次數的做法相比,把count(*)和group by字句相結合使用有許多優點,主要表現在:
在開始統計自前,不必知道被統計的資料列裡面有多少種不同的取值
因為只用了一個查詢命令,我們可以對輸出做排序的處理
select state,count(*) as count from president
group by state order by count desc limt4; //看看出生總統最多的前四個州是哪幾個?
9.4除了count(),我們還用其他一些統計函數,如求出最小值的min(),求最大值的max(),求和的sum(),求平均值的avg(),在實際工作中,這些函數時經常用到的!
*10, 從多個表提取資訊
我們目前的例子都是從一個表裡面提取資訊,但資料庫的真正威力還在於用“關係”來綜合多個資料表裡面的記錄,這種操作稱之為“關聯”或“結合”我們可以看到,select需要給出多個資料表裡面的資訊(不可重複);from需要知道從哪幾個表裡面做事;where則對幾個表之間的關聯資訊作出詳細的描述。
首先我們要學習最可靠的資料列引用方式:資料表名.資料列名。這樣在查詢中就一定不會混淆這個資料列到底在哪一個表裡。
例子1:查詢某一天內的學生們的考試成績,用學號列出。
select scroe.student_id,event_date,score.score,event.type
from event,score
where event.date=’2003-09-12’
and event.event_id=score.event_id
首先,利用event資料表把日期映射到一個考試事件編號,在利用這個編號把score表內相匹配的考試分數找出來。關聯兩個表,一個查詢搞定。
例子2:查詢某一天內的學生們的考試成績,用姓名列出。
select student.name event.name,score.score,event.type
form event,score,student
where event.date=’2003-09-12’
and event.event_id= score.event_id
and scroe.student_id=student.student_id;
關聯三個表,一個查詢搞定。
例子3:查詢一下缺席學生的名字,學號,缺席次數
select student.student_id,student_name
count(absence.date) as absences
from student,absence
where student.student_id=absence.student_id //關聯條件
group by student.student_id;
簡單的關聯操作就介紹到這裡。事實上,對於關聯的知識我們需要學的很多很多,比如說,我們懷疑某一個資料表內不存在和我們相關的資料,把麼在關聯查詢的時候如何處理這個表呢?這就涉及到內聯結,外聯結,左聯結,右聯結的許多新概念了。不知道大家還有沒有信心向下看我的筆記?在本書第四章裡面,對關聯進行了十分詳細的論述,看來“在SQL裡面,幹粗活的是select”的說法再對不過了。
我們瞭解了select命令的如此之多的用法,感到了它的靈活性,許多字句的組合能夠形成一個非常“精妙”的SQL語句,在基礎沒有打好之前,我等初學者目前還沒有必要去鑽研那些技巧性很高的東西,“一定程度的創造性是必要的,但太專業或充滿技巧的代碼則是各種 bug的發源地,同時也是若干個不眠之夜的前奏”