本节要点
数值计算
字段拼接
使用别名
从本节课开始,要学习一些比较复杂的SQL了。
先来看下下面这张表。
这是一张股票交易表(t_stock_trans_dtl),主键是交易编号(trans_id),表中的每一条记录,表示了一条买入或卖出交易,同时记录了交易股票的名称(stock_name)、股票代码(stock_code)、交易时间(opt_tm)、交易类型(opt_typ)、交易价格(price)、交易量(volume)、交易费用(fee)。
其中,股票代码(stock_code)的前两位,代表了是哪个交易所,sh代表上海交易所,sz代表深圳交易所;对于买入交易,交易量为正数,对于卖出交易,交易量为负数;
那么,现在来考虑以下几个查询需求:
手续费保留了5位小数,查询结果只想保留2位小数?
表中只保留了购买单价和数量,那如何取出每笔的交易金额?
如何根据买入数量,区分大单、中单、小单?
表中的操作时间包含了年月日时分秒,只想展示年月日怎么办?
这就需要对表中的原始字段,按照查询需求进行加工后输出。
数值计算
先来讲解下数值计算。考虑下面几个查询需求:
(1)、表中交易数量的单位为股,如何将单位转换为手(1手=100股)后输出?
SELECT trans_id,stock_name,price,volume,volume/100 FROM t_stock_trans_dtl;
(2)、如何根据股票交易表中的单价、数量,计算出交易金额(单价*数量)?
SELECT trans_id,stock_name,price,volume,price*volume FROM t_stock_trans_dtl;
上面的两个例子使用了除法和乘法两个运算符。其实,SQL语言也跟数学中的算术运算一样,也支持加、减、乘、除四则运算。而且运算的优先级也是先乘除、后加减。
比如,SELECT a-b*c/d+1等价于SELECT a-((b*C)/d)+1。不过,虽然这两种写法是等价的,我们还是建议使用括号,明确指定计算的优先级。
另外,在SQL语言中,因为不同数据类型的精度不一样,所以导致除法运算时,不一定会出现我们想要的结果。
比如,对于INT类型的字段a,值为1;INT类型的字段b,值为4,而SELECT a/b的值,一定返回0.25吗?这个真不一定!
假如你要某个数据库(比如Teradata数据库)的计算时,看到a/b返回了0,一定不要惊讶,这是因为字段a与b的数据类型为INT导致的。
最后,需要强调一下,加、减、乘、除这四个算术运算符,仅支持数值类型的值进行计算。
字段拼接
仍然看一下例子:
(1)、如何按“洪都航空(sh600316)”展示股票名称和股票代码?也就是说,将股票名称、股票代码这两个字段的值合并后输出?
一般我们查询时,是这样的:
SELECT stock_name,stock_code FROM t_stock_trans_dtl;
但如果想实现字符串的拼接,就需要使用拼接操作符。不同的数据库,拼接操作符并不完全一样。对于Access、SQL Server数据库,支持的是加号+拼接操作符;
SELECT stock_name + '(' + stock_code + ')' FROM t_stock_trans_dtl;
对于DB2、Oracle、Teradata数据库,支持的是||拼接操作符;
SELECT stock_name || '(' || stock_code || ')' FROM t_stock_trans_dtl;
而MySQL数据库干脆不支持拼接操作符,字符串的拼接使用函数CONCAT来实现。
SELECT CONCAT(stock_name,'(',stock_code,')') FROM t_stock_trans_dtl;
拼接操作符仅支持字符型字段。如果想拼接数值型字段的值,就需要先做一下类型转换,将数值型转换为字符型,然后再拼接。
使用别名
对于我们刚才写出的下面这个拼接的SQL:
SELECT CONCAT(stock_name,'(',stock_code,')') FROM t_stock_trans_dtl;
这个SELECT的结果集中,CONCAT的结果是没有列名的,或者说就使用了这个CONCAT表达式作为了列名。这样在使用这个结果集时,就不太好引用这个列。
在SQL语言中,支持为复杂的表达式取一个别名,想要使用这个表达式的值时,直接使用别名引用。
使用AS关键字为表达式取别名:
SELECT CONCAT(stock_name,'(',stock_code,')') AS stock FROM t_stock_trans_dtl;
上面的别名是一个英文单词,也可以使用中文作为别名:
SELECT CONCAT(stock_name,'(',stock_code,')') AS 股票 FROM t_stock_trans_dtl;
甚至于,中文别名中,还可以有空格。不过这时就需要使用引号将别名引起来:
SELECT CONCAT(stock_name,'(',stock_code,')') AS '股票 名称和代码' FROM t_stock_trans_dtl;
不过,给大家一个建议,尽量不要使用中文别名。如果非要使用,那不论中文别名中是否有空格,都用引号引起来。
本站所有内容均为原创,本站保留所有权利。仅允许非商业用途的转载,但必须注明来源网站、作者、来源链接!否则,由此造成的一切后果,由转载方承担!
干货分享、技术提升、面试笔试、学习交流,欢迎关注公众号:xuesql。QQ学习交流群:209942678。