
如何写好 SQL 代码?
想要锻炼你的编程技能,最简单但最有效的方法之一,就是让你的代码更具可读性(readable)。
让你的代码具有可读性,可以使你的代码更易于解释、更容易重现、而且更容易调试。提高可读性的最佳方法就是坚持执行一系列的规则或标准,以它保持一致和干净。
因此,在本文中,我将给你分享编写优秀的 SQL 代码的八个小技巧。如果你想了解更多SQL相关内容,可以阅读以下这些文章:
3年SQL经验,我总结了十条技巧
你知道吗?SQL也能做机器学习!
实用SQL函数清单——教你用SQL清理数据
手把手教你用Python创建SQL数据库!
1►将关键字符和函数大写
让我从一个你可能已经在做的简单技巧开始,如果你已经这样做了,那这很好,但是你会惊讶有很多人不知道这点:当涉及到关键字和函数的时候,请确保它们是大写的!
虽然这看着像是在吹毛求疵,但这样的技巧会让你的代码清晰十倍。
不要这样写:
select name, date_trunc(register_date, week) from customers
试着这样写:
SELECT name, DATE_TRUNC(register_date, WEEK) FROM customers
2►缩进和对齐
让我们继续,下一个技巧主要集中在代码的缩进和对齐上。思考下面这两个例子——哪个更清晰?
SELECT name, height, age, salary, CASE WHEN age<18 THEN "child" ELSE
"adult" END AS child_or_adult
FROM People LEFT JOIN Income USING (name)
WHERE height<=200 and age<=65
还是:
SELECT
name
, height
, age
, salary
, CASE WHEN age < 18 THEN "child"
ELSE "adult"
END AS child_or_adult
FROM
People
LEFT JOIN
Income USING (name)
WHERE
height <= 200
AND age <= 65
很明显,第二个代码更容易阅读,这完全归功于它的编程格式。特别要注意第二个示例中代码是如何缩进和垂直对齐的。这可以让没见过你代码的人更容易阅读它。
当然,你不必遵循和上面一样的缩进和格式样式,重要的是要运用这个技巧,并在整个代码中使用相同的样式。
3►为数据库/表格/行/列应用统一大小写模式
在编程中,有几种常见的大小写表达类型,这里举几例:
- camelCase
- PascalCase
- snake_case
无论你个人的偏好是什么,在整个代码中保持一致的大小写非常重要。
不要:
SELECT
firstName
, LastName
, child_or_adult
FROM
customers
试着这样写
SELECT
first_name
, last_name
, child_or_adult
FROM
customers
4►避免 SELECT * (select all)
这是一个重要的技巧,不仅适用于格式的优化,还可以对你的查询优化。
即使你几乎使用了表格中的每一列,你最好还是写出需要的列。为什么呢?随着表的发展和更多列的添加/更改,指定你需要的列名能避免未来潜在的识别错误。
不要:
SELECT
*
FROM
customers
尝试用:
SELECT
name
, height
, age
, salary
FROM
customers
5►使用公用表表达式,将代码模块化
使用公用表表达式(common table expressions或 CTE)对模块化和分解代码很有用 – 你可以把它想象成把文章分解为多个段落,方式是类似的 。
使用前:
SELECT
name
, salary
FROM
People
WHERE
name IN (SELECT DISTINCT
name
FROM
population
WHERE
country = "Canada"
AND city = "Toronto")
AND salary >= (SELECT
AVG(salary)
FROM
salaries
WHERE
gender = "Female")
使用后:
with toronto_ppl as (
SELECT DISTINCT
name
FROM
population
WHERE
country = "Canada"
AND city = "Toronto"
)
, avg_female_salary as (
SELECT
AVG(salary) as avg_salary
FROM
salaries
WHERE
gender = "Female"
)
SELECT
name
, salary
FROM
People
WHERE
name IN(SELECT name FROM toronto_ppl)
AND salary >= (SELECT avg_salary FROM avg_female_salary)
现在,我们可以很容易看出 WHERE 函数正在过滤“多伦多(Toronto)”的名字。 CTE 非常有用,因为你不仅可以把代码分解成更小的块,还可以为每个 CTE 分配一个变量名(如上面的 toronto_ppl 和 avg_female_salary)。
说到变量的名字,这就引出了我的下一点:
6►描述性变量名
创建变量名时,你需要让它们描述它们所代表的内容。考虑我之前的例子:
with toronto_ppl as (
SELECT DISTINCT
name
FROM
population
WHERE
country = "Canada"
AND city = "Toronto"
)
, avg_female_salary as (
SELECT
AVG(salary) as avg_salary
FROM
salaries
WHERE
gender = "Female"
)
SELECT
name
, salary
FROM
People
WHERE
name IN(SELECT name FROM toronto_ppl)
AND salary >= (SELECT avg_salary FROM avg_female_salary)
仅通过阅读上面变量名称本身,我们就可以清楚地看出,第一个 CTE 是从多伦多搜索人员,而第二个 CTE 是获取女性的平均工资。
下面举个反面的命名例子,(我以前见过):
with table_one as (
SELECT DISTINCT
name
FROM
population
WHERE
country = "Canada"
AND city = "Toronto"
)
, table_two as (
SELECT
AVG(salary) as var_1
FROM
salaries
WHERE
gender = "Female"
)
SELECT
name
, salary
FROM
People
WHERE
name IN(SELECT name FROM table_one)
AND salary >= (SELECT var_1 FROM table_two)
7►使用临时的函数简化代码
临时函数是一个很好的方法,它们可以:
1. 分解代码
2. 编写更简洁的代码
3. 并且能够重复使用。
考虑以下例子:
SELECT name
, CASE WHEN tenure < 1 THEN "analyst"
WHEN tenure BETWEEN 1 and 3 THEN "associate"
WHEN tenure BETWEEN 3 and 5 THEN "senior"
WHEN tenure > 5 THEN "vp"
ELSE "n/a"
END AS seniority
FROM employees
相反,你可以利用临时函数来使用 CASE 子句。
CREATE TEMPORARY FUNCTION seniority(tenure INT64) AS (
CASE WHEN tenure < 1 THEN "analyst"
WHEN tenure BETWEEN 1 and 3 THEN "associate"
WHEN tenure BETWEEN 3 and 5 THEN "senior"
WHEN tenure > 5 THEN "vp"
ELSE "n/a"
END
);
SELECT name
, seniority(tenure) as seniority
FROM employees
有了临时函数,查询本身就简单多了,而且可读性更强,还可以重复利用!
8►有意义的注释
写注释时,有一个重要的规则:只在需要的时候才写。
通过前面的七个技巧(使用描述性名称、模块化代码、编写干净的代码等),你应该不需要写很多注释。
话虽如此,当代码本身无法解释你要实现的目标时,注释是有用的,并且可能是必需的。
下面是一个不好的注释例子:
# Getting names of people in Toronto, Canada
with table1 as (
SELECT DISTINCT name
FROM population
WHERE country = "Canada"
AND city = "Toronto"
)
# Getting the average salary of females
, table2 as (
SELECT AVG(salary) as var1
FROM salaries
WHERE gender = "Female"
)
这些注释很无用,因为它告诉我的信息是可以通过阅读代码本身就知道的。请记住,注释更多要回答“为什么”你在做某事,而不是“你在做什么”。
谢谢你的阅读!记得订阅我们的公众号,不错过关于数据科学、分析技术技巧、面试求职的文章!你还可以订阅我们的YouTube频道,观看大量数据科学相关公开课:https://www.youtube.com/channel/UCa8NLpvi70mHVsW4J_x9OeQ;在LinkedIn上关注我们,扩展你的人际网络!https://www.linkedin.com/company/dataapplab/
原文作者:Terence Shin
翻译作者:Jiawei Tong
美工编辑:过儿
校对审稿:Jiawei Tong
原文链接:https://towardsdatascience.com/8-best-practices-for-writing-top-tier-sql-code-e1023996e459