SQL基础能力-别名妙用

710 阅读4分钟

之所以把别名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中进行使用,实际计算的是其背后的列或者表。它主要能给使用者带来的好处有

  1. 别名能让SQL的可读性更佳
  2. 当字段名较长或者表明较长的时候,使用别名让编写更容易
  3. 多表关联查询时,避免列名和表命冲突

三、别名的类型

在SQL中两种不同的别名,分别是针对列的-列别名和针对表(临时表)的-表别名

针对列名:

SELECT column as '我是别名' FROM table_name;
  • column 为数据库表中的字段,其也可以是一个方法或者表达式。
  • AS 是使用别名的关键字,当然也可以被省略不写,为了阅读更佳清晰,这里不推荐不使用。
  • '我是别名' 就是指定的别名。

3.1 普通列别名

SELECT `username`  AS '我是列名' from `user`

Mysql 实际测试

image.png

flink 实际测试

image.png

值得注意的是,flink的写法与MySQL有些许不同,flink别名不支持字符串(即用引号标识,而需要用` `才可) 否则报错如下:

image.png

spark 实际测试

image.png

spark 与 flink 处理一致。写习惯了MySQL的同学在这里需要注意。

3.2 表达式列名

SELECT username || '1' AS `我是列名` FROM (select 'tailou' as username UNION  select 'diga' as username) as t;

mysql 实际测试

image.png

flink 实际测试

image.png

spark 实际测试 image.png

这里值得注意的是在MySQL中的运算符与spark、flink中不一致。不同的原因在后续的文章会进行讨论。本文暂时只介绍别名的使用。

3.3 对方法使用别名

在上一篇中介绍SQL顺序时实际已经有用到,可以翻看juejin.cn/post/699032…

3.4 在CASE WHEN中使用别名

mysql 实际测试 image.png

spark 实际测试

image.png

flink 实际测试

image.png

针对表名:

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 实际测试

image.png

spark 实际测试

image.png

flink 实际测试

image.png

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 实际测试 image.png

spark 实际测试

image.png

flink 实际测试

flink 执行报错

image.png

3.9 强制使用

SELECT * from (SELECT 1 as id,'diga' as 'name' UNION SELECT 1 as `no`,'japan' as 'courtry') 

mysql 实际测试 image.png

spark 实际测试

image.png

flink 实际测试

image.png

实验证明,只有MySQL数据库对产生的临时表需要进行强制别名处理,而spark与flink都可以正常不受限制。这也和其底层实现原理不同有莫大的关系。

注:
本文使用的MySQL版本:5.7.33-0ubuntu0.18.04.1
本文使用的spark版本:3.2
本文使用的flink版本:1.13