數(shù)值計(jì)算
字段拼接
使用別名
從本節(jié)課開始,要學(xué)習(xí)一些比較復(fù)雜的SQL了。
先來(lái)看下下面這張表。
這是一張股票交易表(t_stock_trans_dtl),主鍵是交易編號(hào)(trans_id),表中的每一條記錄,表示了一條買入或賣出交易,同時(shí)記錄了交易股票的名稱(stock_name)、股票代碼(stock_code)、交易時(shí)間(opt_tm)、交易類型(opt_typ)、交易價(jià)格(price)、交易量(volume)、交易費(fèi)用(fee)。
其中,股票代碼(stock_code)的前兩位,代表了是哪個(gè)交易所,sh代表上海交易所,sz代表深圳交易所;對(duì)于買入交易,交易量為正數(shù),對(duì)于賣出交易,交易量為負(fù)數(shù);
那么,現(xiàn)在來(lái)考慮以下幾個(gè)查詢需求:
手續(xù)費(fèi)保留了5位小數(shù),查詢結(jié)果只想保留2位小數(shù)?
表中只保留了購(gòu)買單價(jià)和數(shù)量,那如何取出每筆的交易金額?
如何根據(jù)買入數(shù)量,區(qū)分大單、中單、小單?
表中的操作時(shí)間包含了年月日時(shí)分秒,只想展示年月日怎么辦?
這就需要對(duì)表中的原始字段,按照查詢需求進(jìn)行加工后輸出。
先來(lái)講解下數(shù)值計(jì)算??紤]下面幾個(gè)查詢需求:
(1)、表中交易數(shù)量的單位為股,如何將單位轉(zhuǎn)換為手(1手=100股)后輸出?
SELECT
trans_id,stock_name,price,volume,volume/100
FROM t_stock_trans_dtl;
(2)、如何根據(jù)股票交易表中的單價(jià)、數(shù)量,計(jì)算出交易金額(單價(jià)*數(shù)量)?
SELECT
trans_id,stock_name,price,volume,price*volume
FROM t_stock_trans_dtl;
上面的兩個(gè)例子使用了除法和乘法兩個(gè)運(yùn)算符。其實(shí),SQL語(yǔ)言也跟數(shù)學(xué)中的算術(shù)運(yùn)算一樣,也支持加、減、乘、除四則運(yùn)算。而且運(yùn)算的優(yōu)先級(jí)也是先乘除、后加減。
比如,SELECT a-b*c/d 1等價(jià)于SELECT a-((b*C)/d) 1。不過(guò),雖然這兩種寫法是等價(jià)的,我們還是建議使用括號(hào),明確指定計(jì)算的優(yōu)先級(jí)。
另外,在SQL語(yǔ)言中,因?yàn)椴煌瑪?shù)據(jù)類型的精度不一樣,所以導(dǎo)致除法運(yùn)算時(shí),不一定會(huì)出現(xiàn)我們想要的結(jié)果。
比如,對(duì)于INT類型的字段a,值為1;INT類型的字段b,值為4,而SELECT a/b的值,一定返回0.25嗎?這個(gè)真不一定!
假如你要某個(gè)數(shù)據(jù)庫(kù)(比如Teradata數(shù)據(jù)庫(kù))的計(jì)算時(shí),看到a/b返回了0,一定不要驚訝,這是因?yàn)樽侄蝍與b的數(shù)據(jù)類型為INT導(dǎo)致的。
最后,需要強(qiáng)調(diào)一下,加、減、乘、除這四個(gè)算術(shù)運(yùn)算符,僅支持?jǐn)?shù)值類型的值進(jìn)行計(jì)算。
仍然看一下例子:
(1)、如何按“洪都航空(sh600316)”展示股票名稱和股票代碼?也就是說(shuō),將股票名稱、股票代碼這兩個(gè)字段的值合并后輸出?
一般我們查詢時(shí),是這樣的:
SELECT stock_name,stock_code
FROM t_stock_trans_dtl;
但如果想實(shí)現(xiàn)字符串的拼接,就需要使用拼接操作符。不同的數(shù)據(jù)庫(kù),拼接操作符并不完全一樣。對(duì)于Access、SQL Server數(shù)據(jù)庫(kù),支持的是加號(hào) 拼接操作符;
SELECT stock_name '(' stock_code ')'
FROM t_stock_trans_dtl;
對(duì)于DB2、Oracle、Teradata數(shù)據(jù)庫(kù),支持的是||拼接操作符;
SELECT stock_name || '(' || stock_code || ')'
FROM t_stock_trans_dtl;
而MySQL數(shù)據(jù)庫(kù)干脆不支持拼接操作符,字符串的拼接使用函數(shù)CONCAT來(lái)實(shí)現(xiàn)。
SELECT CONCAT(stock_name,'(',stock_code,')')
FROM t_stock_trans_dtl;
拼接操作符僅支持字符型字段。如果想拼接數(shù)值型字段的值,就需要先做一下類型轉(zhuǎn)換,將數(shù)值型轉(zhuǎn)換為字符型,然后再拼接。
對(duì)于我們剛才寫出的下面這個(gè)拼接的SQL:
SELECT CONCAT(stock_name,'(',stock_code,')')
FROM t_stock_trans_dtl;
這個(gè)SELECT的結(jié)果集中,CONCAT的結(jié)果是沒有列名的,或者說(shuō)就使用了這個(gè)CONCAT表達(dá)式作為了列名。這樣在使用這個(gè)結(jié)果集時(shí),就不太好引用這個(gè)列。
在SQL語(yǔ)言中,支持為復(fù)雜的表達(dá)式取一個(gè)別名,想要使用這個(gè)表達(dá)式的值時(shí),直接使用別名引用。
使用AS關(guān)鍵字為表達(dá)式取別名:
SELECT CONCAT(stock_name,'(',stock_code,')') AS stock
FROM t_stock_trans_dtl;
上面的別名是一個(gè)英文單詞,也可以使用中文作為別名:
SELECT CONCAT(stock_name,'(',stock_code,')') AS 股票
FROM t_stock_trans_dtl;
甚至于,中文別名中,還可以有空格。不過(guò)這時(shí)就需要使用引號(hào)將別名引起來(lái):
SELECT CONCAT(stock_name,'(',stock_code,')') AS '股票 名稱和代碼'
FROM t_stock_trans_dtl;
不過(guò),給大家一個(gè)建議,盡量不要使用中文別名。如果非要使用,那不論中文別名中是否有空格,都用引號(hào)引起來(lái)。
課后習(xí)題:
1、對(duì)于第6課課后習(xí)題中的論壇注冊(cè)用戶表,請(qǐng)編寫SQL完成以下查詢。
(1)、查詢所有用戶信息,將用戶名及手機(jī)號(hào)合并顯示,如“獅子(Tel:13882694448)”。
(2)、根據(jù)用戶的最近登錄時(shí)間,查詢廣東省的用戶中,最近有多少天未登錄論壇。
(3)、查詢每個(gè)用戶,平均每多天登錄一次。如某用戶從注冊(cè)到現(xiàn)在已經(jīng)經(jīng)過(guò)了100天,但只登錄過(guò)5,說(shuō)明該用戶平均每20天登錄一次。
聯(lián)系客服