之所以把别名alias选为第二篇,最主要的原因还是因为它在SQL中太常见了,几乎无处不在。尤其在多层嵌套查询以及联表查询中必备,学会了使用别名,对于编写美观简洁的SQL也有非常大的帮助。对其他人员阅读起来也会感到赏心悦目。
一、别名实例
随便节选部分ETL中的SQL演示一下。
select distinct store_id,
store_product_id,
product_id,
min(time_review) as time_review
from (
select store_id_in as store_id,
store_product_id_in as store_product_id,
time_review_in as time_review,
product_id
from (select store_id_in, store_product_id_in, time_review_in, product_id
from table1
WHERE FROM_UNIXTIME(time_review_in / 1000l, 'yyyyMMdd') =
FROM_UNIXTIME(unix_timestamp('${year}${month}${day}', 'yyyyMMdd'), 'yyyyMMdd')
and status_review_in = 40
)
union
(
select store_id, store_product_id, time_review, product_id
from (
select warehousing_id,
product_id,
store_product_id,
min(time_review) as time_review
from table2
WHERE FROM_UNIXTIME(time_review / 1000l, 'yyyyMMdd') =
FROM_UNIXTIME(unix_timestamp('${year}${month}${day}', 'yyyyMMdd'), 'yyyyMMdd')
and review_status = 10
and meta_type != 'DELETE'
group by warehousing_id, product_id, store_product_id
) wsd
inner join
(
select id
, store_id
from table3
where meta_type != 'DELETE'
) ws
on ws.id = wsd.warehousing_id
left join stores st on ws.store_id = st.id
where st.meta_type != 'DELETE'
)
)
group by store_id, store_product_id, product_id;
案例中存在有好几处地方都使用了别名。
二、别名的意义
在查询过程中,SQL允许通过人为的对字段或者表指定一个临时的名字。这个名字在整个查询期间都有效,或者可以简单理解为,别名作为一个参数引用,使用该别名参数就可以像在程序中使用参数一样在SQL中进行使用,实际计算的是其背后的列或者表。它主要能给使用者带来的好处有
- 别名能让SQL的可读性更佳
- 当字段名较长或者表明较长的时候,使用别名让编写更容易
- 多表关联查询时,避免列名和表命冲突
三、别名的类型
在SQL中两种不同的别名,分别是针对列的-列别名和针对表(临时表)的-表别名
针对列名:
SELECT column as '我是别名' FROM table_name;
- column 为数据库表中的字段,其也可以是一个方法或者表达式。
- AS 是使用别名的关键字,当然也可以被省略不写,为了阅读更佳清晰,这里不推荐不使用。
- '我是别名' 就是指定的别名。
3.1 普通列别名
SELECT `username` AS '我是列名' from `user`
Mysql 实际测试
flink 实际测试
值得注意的是,flink的写法与MySQL有些许不同,flink别名不支持字符串(即用引号标识,而需要用` `才可) 否则报错如下:
spark 实际测试
spark 与 flink 处理一致。写习惯了MySQL的同学在这里需要注意。
3.2 表达式列名
SELECT username || '1' AS `我是列名` FROM (select 'tailou' as username UNION select 'diga' as username) as t;
mysql 实际测试
flink 实际测试
spark 实际测试
这里值得注意的是在MySQL中的运算符与spark、flink中不一致。不同的原因在后续的文章会进行讨论。本文暂时只介绍别名的使用。
3.3 对方法使用别名
在上一篇中介绍SQL顺序时实际已经有用到,可以翻看juejin.cn/post/699032…
3.4 在CASE WHEN中使用别名
mysql 实际测试
spark 实际测试
flink 实际测试
针对表名:
SELECT column as '我是别名' FROM table_name as t;
- 使用表别名最大的好处是可以在表名重复时,有巨大的帮助。尤其是在ETL中,抽取不同数据源的情况难免,其中不免有一些表名重复。使用别名能极大方便SQL的编写。
- 在多张表进行组合成大表时,别名可以加快编写速度。
- 同样,在命名别名过程中,AS关键字也是可以省略的,但是同样不建议省略。
常用的表别名命名方式通常是表名的缩写,例如
- employee e
- employee emp
- product p
- product pr
- customer c
- customer cust
- bill_usage_line_items bli
这对理解SQL有很大的帮助。另外一种命名方式可能是根据表名的驼峰命名法进行首字母抽取。这里不进行拓展,可根据个人喜好进行选择。并没有强制要求。
3.5 简单的表别名
上面内容中的部分案例已经使用了表别名,这里不再进行验收,可以上翻查阅。
3.6 在where语句中使用表别名
SELECT `username` AS `名字` FROM( SELECT 'tailou' AS username UNION SELECT 'diga' AS username ) AS t WHERE t .username = 'diga';
mysql 实际测试
spark 实际测试
flink 实际测试
3.7 在having语句中使用
在上一篇中介绍SQL顺序时实际已经有用到,可以翻看juejin.cn/post/699032…
3.8 在join中使用
SELECT * from((SELECT 1 as id,'diga' as 'name') t1 JOIN (SELECT 1 as `no`,'japan' as 'courtry') t2 ON t1.id = t2.no)
mysq 实际测试
spark 实际测试
flink 实际测试
flink 执行报错
3.9 强制使用
SELECT * from (SELECT 1 as id,'diga' as 'name' UNION SELECT 1 as `no`,'japan' as 'courtry')
mysql 实际测试
spark 实际测试
flink 实际测试
实验证明,只有MySQL数据库对产生的临时表需要进行强制别名处理,而spark与flink都可以正常不受限制。这也和其底层实现原理不同有莫大的关系。
注:
本文使用的MySQL版本:5.7.33-0ubuntu0.18.04.1
本文使用的spark版本:3.2
本文使用的flink版本:1.13