使SQL更易于阅读的几个小技巧

简介: 无论是数仓开发还是数据分析,写一手好的SQL是一项基本的技能。毋庸置疑,编写性能较好的SQL是非常重要的,但是,SQL的可读性同样是不容小觑的。一个有着混乱格式的SQL脚本,往往需要花费较长的时间去弄清楚脚本的具体逻辑。


 



无论是数仓开发还是数据分析,写一手好的SQL是一项基本的技能。毋庸置疑,编写性能较好的SQL是非常重要的,但是,SQL的可读性同样是不容小觑的。一个有着混乱格式的SQL脚本,往往需要花费较长的时间去弄清楚脚本的具体逻辑。如果你曾经被祖传的毫无章法的SQL脚本狂虐过,你一定心有感触。本文将分享几个SQL格式的规范,当然仁者见仁智者见智,其实没有严格的标准,如果有,那就是保证易于阅读和易于维护。


大小写保持一致


可以对SQL关键字使用不同的大小写,但是要保持一致。看看这个:


SELECT customer_city,count(*) from dim_customer WHERE customerProvince = '上海' Group by customer_city

上面的SQL语句是不是很让人抓狂,大小写混用,看起来很不规范。总结起来,要注意下面几点:



  • SQL的关键字可以大写,也可以小写,但是不要大小写混用。上面的SQL查询既有完全大写,也有首字母大写,更有小写。看似是不拘小节,但是万万使不得。
  • 由于大小写是混合的,因此很难区分小写的关键字实际上是关键字还是列。此外,阅读也很烦人。
  • 字段命名要保持一致的风格,上面的SQL与中customer_city是小写加下划线,而customerProvince字段是驼峰命名法,这种不一致性显然是不可取的。

进行一些规范之后后,查询应如下所示:


SELECT customer_city,
   count(*)

FROM dim_customer
WHERE customer_province = '上海'
GROUP BY customer_city


使用缩进


再来看看下面的一条查询语句:


SELECT dp.region_name,count(*) FROM user_behavior_log ubl JOIN dim_province dp ON ubl.province = dp.province_name WHERE ubl.province = '上海市' GROUP BY dp.region_name

将上面的SQL语句格式化下面的形式:


SELECT dp.region_name, count(*)
FROM user_behavior_log ubl
JOIN dim_province dp ON ubl.province = dp.province_name
WHERE ubl.province = '上海市'
GROUP BY dp.region_name

上面的格式化形式似乎清晰了很多,但是如果语句中包含了子查询、多个JOIN以及窗口函数时,同样会显得对阅读不是很友好。


再换一种格式化方式,如下:


SELECT
dp.region_name, 
count(*)

FROM user_behavior_log ubl

JOIN dim_province dp ON ubl.province = dp.province_name

WHERE ubl.province = '上海市'
GROUP BY

dp.region_name

-- 或者下面的形式
SELECT

dp.region_name 
,count(*)

FROM user_behavior_log ubl

JOIN dim_province dp ON ubl.province = dp.province_name

WHERE ubl.province = '上海市'
GROUP BY

dp.region_name</code></pre>

尖叫提示:对于第二种形式,在SELECT字段中,从第二个字段开始,每个字段前面添加一个逗号,而不是每个字段后面使用逗号结尾。这种方式可以很方便地识别FROM前面是否存在逗号,从而造成语法错误。当然,这个只是个人习惯问题,并不是硬性的规定。


另外上面的SQL语句使用了4个字符缩进,当然也可以选择2个字符缩进,这个也是个人习惯问题。


在group by 和order by之后使用字段的排列序号


同样,这种书写风格也是个人的一种偏好,并不是一条硬性规定。应该有很多的初学者对此种写法并不是很清楚。


看下面的这条SQL:


SELECT
dp.region_name, 
dp.province_name,
count(*)

FROM user_behavior_log ubl

JOIN dim_province dp ON ubl.province = dp.province_name

GROUP BY

dp.region_name,
dp.province_name

ORDER BY

count(*) desc -- Hive不支持</code></pre>

可以写成下面的形式:


-- 注意:MySQL、Impala支持这种写法,Hive不支持

SELECT

dp.region_name, 
dp.province_name,
count(*)

FROM user_behavior_log ubl

JOIN dim_province dp ON ubl.province = dp.province_name

GROUP BY 1,2
ORDER BY 3


这样写有如下的好处:



可以节省行:通过许多字段进行分组不仅会在SELECT子句中添加更多行,还会在GROUP BY和ORDER BY子句中添加更多行,甚至可能使查询中的行数增加一倍。
可维护性:如果想改变分组字段,只需在SELECT子句中进行操作,在GROUP BY语句中不需要修改。
方便:只需要GROUP BY 1,2,3,…,n,其中n为分组列的字段序号。

使用Common Table表达式(with语句)


该方式称之为Common Table Expressions(CTE),用来简化复杂查询。它们可以定义为临时视图,因为它们仅在整个查询执行期间存在。


看一个简单的例子:


-- 注意Hive、Impala支持这种语法,低版本的MySQL不支持(高版本支持)
WITH employee_by_title_count AS (
SELECT
    t.name as job_title
    , COUNT(e.id) as amount_of_employees
FROM employees e
    JOIN job_titles t on e.job_title_id = t.id
GROUP BY 1

),
salaries_by_title AS (

 SELECT
     name as job_title
     , salary
 FROM job_titles

)
SELECT *
FROM employee_by_title_count e

JOIN salaries_by_title s ON s.job_title = e.job_title</code></pre>

上面的语句中,最终的查询使用employee_by_title和salaries_by_title的两个结果集进行JOIN产生最终结果。这比在SELECT子句中或直接在FROM子句中进行子查询更具可读性和可维护性。


使用具有描述性的别名


这一点非常重要,如果查询的列字段很多,肯能会存在一些id,count(*)等,很难辨识代表什么含义,所以需要为每个查询列加上可读的、易于理解的别名,能够让其他人一眼就能看出代表什么含义,这样可以增加脚本的可维护性。


总结


文中提到的一些规范有些是必须要遵守的,有些是个人的编码习惯,无论你是开发人员、数据分析师、数仓开发,遵循一些规范可以避免不必要的麻烦。值得注意的是,关于SQL的格式,没有一个标准的约定,需要与团队的其他成员达成共识,一起按照相同的约定进行开发,从而可以大大提高脚本的可读性和可维护性。





本文作者:西贝木土



目录
相关文章
|
3月前
|
SQL 测试技术 项目管理
轻松学习SQL外键约束的核心原理和实用技巧
轻松学习SQL外键约束的核心原理和实用技巧
48 0
|
SQL 存储 数据可视化
程序员必须清楚的 10 个高级 SQL 概念!
随着数据量持续增长,对合格数据专业人员的需求也会增长。具体而言,对SQL流利的专业人士的需求日益增长,而不仅仅是在初级层面。 因此,Stratascratch的创始人Nathan Rosidi以及我觉得我认为10个最重要和相关的中级到高级SQL概念。
127 0
程序员必须清楚的 10 个高级 SQL 概念!
|
SQL 数据挖掘
使SQL更易于阅读的几个小技巧
无论是数仓开发还是数据分析,写一手好的SQL是一项基本的技能。毋庸置疑,编写性能较好的SQL是非常重要的,但是,SQL的可读性同样是不容小觑的。一个有着混乱格式的SQL脚本,往往需要花费较长的时间去弄清楚脚本的具体逻辑。
335 0
|
SQL BI 数据库
提高SQL语言能力必会的知识点
想要进一步提高SQL语言能力必须完全理解SQL执行过程
5780 0
提高SQL语言能力必会的知识点
|
存储 SQL 关系型数据库
部分 I. 教程_第 2 章 SQL语言_2.2. 概念
2.2. 概念 PostgreSQL是一种关系型数据库管理系统 (RDBMS)。这意味着它是一种用于管理存储在关系中的数据的系统。关系实际上是表的数学术语。 今天,把数据存储在表里的概念已经快成了固有的常识了, 但是还有其它的一些方法用于组织数据库。
1057 0
|
SQL 存储 数据库
SQL反模式:SQL 建模与使用指南
上周末花了几个小时刷完《SQL反模式》这本书,书里介绍了数据库应用开发者最长遇到的一些问题,虽然这本书面向的读者是使用数据库的应用开发者,但它对数据库管理员、数据库开发者同样会有启发,强烈推荐阅读。
|
SQL 数据库
《《SQL与关系数据库理论——如何编写健壮的SQL代码》》一导读
SQL无所不在。尽管如此,SQL却难以使用:SQL是复杂的,令人困惑且容易出错(我敢说比它的卫道士所声称的更容易出错)。所以,为了写出你能确信的精确SQL代码(意思是它准确地做到了要求它做的事),你就必须遵从一些适当的准则。
1461 0
|
SQL Oracle 关系型数据库
《SQL与关系数据库理论——如何编写健壮的SQL代码》一1.3 原理而非产品
本节书摘来华章计算机《SQL与关系数据库理论——如何编写健壮的SQL代码》一书中的第1章 ,第1.1节 C. J. Date 著 单世民 何英昊 许侃 译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1120 0