SQL语句通常不容易理解,尤其是当您阅读别人编写的语句时。因此,很多人指出,我们应该遵循其他语言所遵循的原则,比如注解和功能模块化。我****注意到一个没有多少人使用的关键Postgres功能,@timonk在他关于数据仓库服务Redshift的AWSRe:Invent主题演讲中指出了这一点。这个特性实际上使SQL既可读又模块化。以前回头看自己几个月前的SQL语句,往往看不懂,现在可以了。此功能是CTE,或公用表表达式,或者您可以称之为WITH语句。就像数据库中的视图一样,它的主要好处是它允许您在当前事务中创建临时表。你可以大量使用它,因为它可以让你以清晰的思路搭积木,也很容易让别人明白你在做什么。让我们举一个简单的例子WITHusers_tasksAS(SELECTusers.email,array_agg(tasks.name)astask_list,projects.titleFROMusers,tasks,projectWHEREusers.id=tasks.user_idprojects.title=tasks.project_idGROUPBYusers.email,projects.title)由临时表users_tasks定义,我可以稍后为users_tasks添加基本查询语句,例如:SELECT*FROMusers_tasks;有趣的是,您可以将它们连接在一起。当我知道分配给每个用户的任务量时,也许我想知道谁负责超过50%的给定任务,从而导致瓶颈。为了化繁为简,我们可以采用多种方法,先计算每项任务的总金额,然后再计算每个人负责每项任务的总金额。total_tasks_per_projectAS(SELECTproject_id,count(*)astask_countFROMtasksGROUPBYproject_id),tasks_per_project_per_userAS(SELECTuser_id,project_id,count(*)astask_countFROMtasksGROUPBYuser_id,project_id),现在我们将组合一下然后发现超过50%的用户overloaded_usersAS(SELECTtasks_per_project_per_user.user_id,FROMtasks_per_project_per_user,total_tasks_per_projectWHEREtasks_per_project_per_user.task_count>(total_tasks_per_project/2))最终目标,我想获得一个以逗号分隔的超载用户和任务列表。我们只需加入overloaded_users和users_tasks的初始列表。放在一起可能有点长,但它的可读性很强。作为额外的帮助,我在每一层上添加了注释。---CreatedbyCraigKerstiens11/18/2013---Queryhighlightsusersthathaveover50%oftasksonagivenproject---Givescommaseparatedlistoftheirtasksandtheproject---InitialquerytograbprojecttitleandtasksperuserWITHusers_tasksAS(SELECTusers.idasuser_id,users.email,array_agg(tasks.name)astask_list,projects.titleFROMusers,tasks,projectWHEREusers.id=tasks.user_idprojects.title=tasks.project_idGROUPBYusers.email,projects.title),---Calculatesthetotaltaskspereachprojecttotal_tasks_per_projectAS(SELECTproject_id,count(*)astask_countFROMtasksGROUPBYproject_id),---Calculatestheprojectspereachusertasks_per_project_per_userAS(SELECTuser_id,project_id,count(*)astask_countFROMtasksGROUPBYuser_id,project_id),---Getsuseridsthathaveover50%oftasksassignedoverloaded_usersAS(SELECTtasks_per_project_per_user.user_id,FROMtasks_per_project_per_user,total_tasks_per_projectWHEREtasks_per_project_per_user.task_count>(total_tasks_per_project/2))SELECTemail,task_list,titleFROMusers_tasks,overloaded_usersWHEREusers_tasks.user_id=overloaded_users.user_idCTEs通常没有精简和优化的SQL语句性能高,大部分差距都不到两倍。对我来说,这种可读性的妥协是毋庸置疑的。Postgres优化器将来肯定会在这方面做得更好。请注意,是的,我可以用大约10-15行简短的SQL来做同样的事情,但您可能无法很快理解它。当您需要确保SQL做正确的事情时,可读性的优势就来了。SQL语句总是有一个结果,你对此毫无疑问。确保您的SQL语句易于推理是正确性的关键。原文链接:http://www.craigkerstiens.com/2013/11/18/best-postgres-feature-youre-not-using/
