SQL格式标准

在我上一份工作中,我们研究了一个非常重要的数据库应用程序,并且开发了一些格式化标准,这样我们就可以用通用的布局编写SQL。 我们也开发了编码标准,但是这些都是更具体的平台,所以我不会在这里讨论它们。

我很想知道其他人使用SQL格式标准。 与大多数其他编码环境不同,因为我没有在网上find很多共识。

要涵盖主要的查询types:

select ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 from SourceTable ST inner join JoinTable JT on JT.SourceTableID = ST.SourceTableID inner join SecondJoinTable SJT on ST.SourceTableID = SJT.SourceTableID and JT.Column3 = SJT.Column4 where ST.SourceTableID = X and JT.ColumnName3 = Y 

在“select”,“from”和“where”之后,对换行有一些不同意见。 select线上的意图是允许其他操作员(如“顶部X”)不改变布局。 接下来,简单地在关键查询元素之后保持一致的换行,似乎导致了良好的可读性水平。

在“from”和“where”之后放弃换行是一个可以理解的修改。 然而,在诸如下面的“更新”这样的查询中,我们看到“where”之后的换行给了我们很好的列alignment。 同样,在“group by”或“order by”之后的换行使我们的列布局清晰易读。

 update TargetTable set ColumnName1 = @value, ColumnName2 = @value2 where Condition1 = @test 

最后一个插入:

 insert into TargetTable ( ColumnName1, ColumnName2, ColumnName3 ) values ( @value1, @value2, @value3 ) 

在大多数情况下,这些不会偏离MS SQL Serverpipe理工作室 /查询分析器写出SQL的方式,但它们确实有所不同。

我期待看到Stack Overflow社区是否有共识。 我经常惊讶有多less开发人员可以遵循其他语言的标准格式,并在碰到SQL时突然变得如此随机。

我认为,只要你可以轻易地阅读源代码,格式是次要的。 只要达到这个目标,那么就可以采用一些很好的布局风格。

唯一对我很重要的方面是,无论你select在你的店铺采用什么样的编码布局/风格,确保它被所有的编码人员一致使用。

仅供参考,以下是我将如何展示您提供的示例,只是我的布局首选项。 特别值得注意的是,ON子句与连接位于同一行,只有主要连接条件在连接中列出(即键匹配),其他条件则移至where Cluase。

 select ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 from SourceTable ST inner join JoinTable JT on JT.SourceTableID = ST.SourceTableID inner join SecondJoinTable SJT on ST.SourceTableID = SJT.SourceTableID where ST.SourceTableID = X and JT.ColumnName3 = Y and JT.Column3 = SJT.Column4 

一个提示,让自己从红门SQL提示的副本。 您可以自定义工具以使用您所需的布局偏好,然后您店铺中的编码人员都可以使用它来确保每个人都采用相同的编码标准。

迟到的答案,但希望有用

作为大型开发团队的一部分,我的经验是,您可以继续并定义您喜欢的任何标准,但是问题实际上是在强制执行这些标准,或者使开发人员很容易实现。

作为开发人员,我们有时会创build一些有用的东西,然后说“我会稍后格式化”,但是以后再也不会出现。

最初我们使用了SQL Prompt(这很棒),但是后来切换到了ApexSQL Refactor,因为它是一个免费的工具。

我迟到了,但是我只是添加了自己喜欢的格式风格,我从书本和手册中学到了一些:它很紧凑。 以下是示例SELECT语句:

 SELECT st.column_name_1, jt.column_name_2, sjt.column_name_3 FROM source_table AS st INNER JOIN join_table AS jt USING (source_table_id) INNER JOIN second_join_table AS sjt ON st.source_table_id = sjt.source_table_id AND jt.column_3 = sjt.column_4 WHERE st.source_table_id = X AND jt.column_name_3 = Y 

简而言之:8位缩进,大写关键字(尽pipeSO使用小写字母时颜色更好),没有camelcase(在Oracle上没有意义),需要时换行。

UPDATE

 UPDATE target_table SET column_name_1 = @value, column_name_2 = @value2 WHERE condition_1 = @test 

INSERT

 INSERT INTO target_table (column_name_1, column_name_2, column_name_3) VALUES (@value1, @value2, @value3) 

现在,让我成为第一个承认这种风格存在问题的人。 8空格缩进意味着ORDER BYGROUP BY或者不alignment缩进,或者将BY分开。 缩进WHERE子句的整个谓词也是比较自然的,但我通常在左边界处alignmentANDOR运算符。 包装INNER JOIN行之后的缩进也有些随意。

但是无论出于什么原因,我仍然觉得比其他select更容易阅读。

我将用我最近使用这种格式风格的更复杂的作品之一完成。 几乎在SELECT语句中遇到的所有内容都出现在这个列表中。 (它也被改变成掩饰它的起源,而且我可能在这么做时引入了错误。)

 SELECT term, student_id, CASE WHEN ((ft_credits > 0 AND credits >= ft_credits) OR (ft_hours_per_week > 3 AND hours_per_week >= ft_hours_per_week)) THEN 'F' ELSE 'P' END AS status FROM ( SELECT term, student_id, pm.credits AS ft_credits, pm.hours AS ft_hours_per_week, SUM(credits) AS credits, SUM(hours_per_week) AS hours_per_week FROM ( SELECT e.term, e.student_id, NVL(o.credits, 0) credits, CASE WHEN NVL(o.weeks, 0) > 5 THEN (NVL(o.lect_hours, 0) + NVL(o.lab_hours, 0) + NVL(o.ext_hours, 0)) / NVL(o.weeks, 0) ELSE 0 END AS hours_per_week FROM enrollment AS e INNER JOIN offering AS o USING (term, offering_id) INNER JOIN program_enrollment AS pe ON e.student_id = pe.student_id AND e.term = pe.term AND e.offering_id = pe.offering_id WHERE e.registration_code NOT IN ('A7', 'D0', 'WL') ) INNER JOIN student_history AS sh USING (student_id) INNER JOIN program_major AS pm ON sh.major_code_1 = pm._major_code AND sh.division_code_1 = pm.division_code WHERE sh.eff_term = ( SELECT MAX(eff_term) FROM student_history AS shi WHERE sh.student_id = shi.student_id AND shi.eff_term <= term) GROUP BY term, student_id, pm.credits, pm.hours ) ORDER BY term, student_id 

这种可憎的方法是计算一个学生在某个学期是全职还是兼职。 不pipe风格如何,这个很难看。

尼斯。 作为一名Python程序员,以下是我的偏好:

“select”,“从”和“哪里”之后的新线只有在需要可读性的时候。

当代码可以更紧凑和可读性更好时,我通常更喜欢更紧凑的forms。 能够在一个屏幕上embedded更多的代码可以提高生产力。

 select ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 from SourceTable ST inner join JoinTable JT on JT.SourceTableID = ST.SourceTableID inner join SecondJoinTable SJT on ST.SourceTableID = SJT.SourceTableID and JT.Column3 = SJT.Column4 where ST.SourceTableID = X and JT.ColumnName3 = Y 

最终,这将是一个将在代码审查期间作出的判断呼叫。

对于insert ,我会不同地放置parens:

 insert into TargetTable ( ColumnName1, ColumnName2, ColumnName3) values ( @value1, @value2, @value3) 

这种格式的推理是,如果SQL使用块结构的标识(如Python),那么括号就不需要了。 所以如果使用缩进,那么parens应该对布局有最小的影响。 这是通过将它们放在线的末尾来实现的。

 SELECT a.col1 AS [Column1] ,b.col2 AS [Column2] ,c.col1 AS [Column3] FROM Table1 a INNER JOIN Table2 b ON b.Id = a.bId INNER JOIN Table3 c ON c.Id = a.cId WHERE a.col = X AND b.col = Y 

使用更多的线比这里的很多例子,但我觉得它更容易理解,可以快速删除列/子句/表。 它有助于利用垂直方向的显示器。

我倾向于使用类似于你的布局,虽然我甚至进一步去了几步,例如: –

 select ST.ColumnName1 , JT.ColumnName2 , SJT.ColumnName3 from SourceTable ST inner join JoinTable JT on JT.SourceTableID = ST.SourceTableID inner join SecondJoinTable SJT on ST.SourceTableID = SJT.SourceTableID where ST.SourceTableID = X and JT.ColumnName3 = Y and JT.Column3 = SJT.Column4 

也许它起初看起来有点过头了,但恕我直言,这种方式使用列表给出了最清晰,最系统的布局,给出了SQL的声明性质。

最后你可能会得到各种各样的答案,最后归结为个人或团队同意的偏好。

除了将“ON”关键字放在连接的同一行上,我在行尾加上“AND”和“OR”运算符,以便我所有的join/select条件排队很好。

虽然我的风格与John Sansom的风格很相似,但我不同意在WHERE子句中join联合标准。 我认为它应该与联合表,以便组织和容易find。

我也倾向于把新括号放在新的行上,与上面的行alignment,然后在下一行缩进,尽pipe对于简短的陈述,我可能只是将括号保留在原始行上。 例如:

 SELECT my_column FROM My_Table WHERE my_id IN ( SELECT my_id FROM Some_Other_Table WHERE some_other_column IN (1, 4, 7) ) 

对于CASE语句,我给每个WHEN和ELSE一个新的行和缩进,我把ENDalignment到CASE:

 CASE WHEN my_column = 1 THEN 'one' WHEN my_column = 2 THEN 'two' WHEN my_column = 3 THEN 'three' WHEN my_column = 4 THEN 'four' ELSE 'who knows' END 

我意识到我这个辩论已经很晚了,但我想提出我的想法。 在线开始的时候我绝对赞成逗号。 就像你说AdamRalph那样,更容易评论一个领域,而且我也发现当他们刚刚开始的时候,错过了一个逗号比较难,而这听起来不像是我过去花了几个小时的大问题追踪冗长的T-SQL程序中的意外语法错误,在这些程序中,我意外错过了行尾的逗号(我相信你们中的一些人可能也这样做了)。 我也尽可能地支持锯齿。

总的来说,虽然我意识到这一切都归个人喜好,但对一些人有用的东西不适合其他人。 只要您可以轻松阅读代码,并且每个开发人员都会在自己的风格中performance出一致性,那么我认为这是最重要的。

我正在C#中编写一个开源SQL格式化程序(仅在此阶段的SQL Server),所以我通过它来进行上述查询。

它采用了与OP类似的策略,即每个“部分”都有缩进的子元素。 在需要的地方,我会在各部分之间添加空白区域,以便清晰起见 – 当没有连接时或在最小条件时,不会添加这些空白区域

结果:

 SELECT ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 FROM SourceTable ST INNER JOIN JoinTable JT ON JT.SourceTableID = ST.SourceTableID INNER JOIN SecondJoinTable SJT ON ST.SourceTableID = SJT.SourceTableID AND ST.SourceTable2ID = SJT.SourceTable2ID WHERE ST.SourceTableID = X AND JT.ColumnName3 = Y AND JT.Column3 = SJT.Column4 ORDER BY ST.ColumnName1 

根据约翰的build议,我会build议以下的风格:

 /* <Query title> <Describe the overall intent of the query> <Development notes, or things to consider when using/interpreting the query> */ select ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 from -- <Comment why this table is used, and why it's first in the list of joins> SourceTable ST -- <Comment why this join is made, and why it's an inner join> inner join JoinTable JT on ST.SourceTableID = JT.SourceTableID -- <Comment why this join is made, and why it's an left join> left join SecondJoinTable SJT on ST.SourceTableID = SJT.SourceTableID and JT.Column3 = SJT.Column4 where -- comment why this filter is applied ST.SourceTableID = X -- comment why this filter is applied and JT.ColumnName3 = ( select somecolumn from sometable ) ; 

优点:
评论是使代码可读和检测错误的重要部分。
– 向联接添加-all-“on”筛选器可避免从内部联接到左联接时出错。
– 将分号放在换行符上可以方便地添加/评论where子句。

晚了,但我会把帽子扔在戒指里。 编写需要更长的时间,但是我发现模式出现在垂直alignment中,一旦习惯了它,它就会非常可读。

 SELECT ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3, CASE WHEN condition1 = True AND condition2 = True Then DoSomething Else DoSomethingElse END ColumnName4 FROM SourceTable AS ST INNER JOIN JoinTable AS JT ON JT.SourceTableID = ST.SourceTableID INNER JOIN SecondJoinTable AS SJT ON ST.SourceTableID = SJT.SourceTableID AND JT.Column3 = SJT.Column4 LEFT JOIN (SELECT Column5 FROM Table4 QUALIFY row_number() OVER ( PARTITION BY pField1, pField2 ORDER BY oField1 ) = 1 ) AS subQry ON SJT.Column5 = subQry.Column5 WHERE ST.SourceTableID = X AND JT.ColumnName3 = Y 

如果我正在对已经写好的T-SQL进行更改,那么我遵循已经使用的约定(如果有的话)。

如果我从头开始编写或没有任何约定,那么我倾向于遵循问题中给出的约定,除了我更喜欢使用大写字母作为关键字(只是个人偏好的可读性)。

我认为,与其他代码格式惯例一样,使用SQL格式,重要的是要有一个惯例,而不是惯例(在常识的范围内)!

是的,我可以看到以一种严格定义的方式布置你的SQL的价值,但是命名约定和你的意图当然更重要。 像十倍重要。

基于我的宠物仇恨是前缀为tbl的表和以sp为前缀的存储过程 – 我们知道它们是表和SP。 DB对象的命名比有多less个空间要重要得多

只是我的$ 0.02的价值

我在SSMS中使用了Red Gate SQL ReFactor,但另一个重新格式化的工具是Apex的SQL Edit 。 如果你想在网上发布代码,那么就是The Simple-Talk SQL Prettifier 。

我喜欢:

 SELECT ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 --leave all selected columns on the same line FROM SourceTable ST INNER JOIN JoinTable JT ON JT.SourceTableID = ST.SourceTableID INNER JOIN SecondJoinTable SJT --only splitting lines when more than 1 condition ON ST.SourceTableID = SJT.SourceTableID AND JT.Column3 = SJT.Column4 WHERE ST.SourceTableID = X and JT.ColumnName3 = Y 

在更小的可视区域获得更多的代码。 我也相信关键字应该是首都

这个线程有很多好处。 我一直试图说服人们使用的一个标准是把逗号放在每一列之前的同一行上。 像这样:

 Select column1 ,column2 ,column3 ,column4 ,Column5 ...ect 

反对:

 Select column1, column2, column3, ect... 

我更喜欢这种做法的原因是因为,如果有必要,你可以注释掉一行,当你运行它的时候也不会是一个逗号问题,因为相应的逗号也会被注释掉。 我知道我在线程中看到了另一个用户,但是并没有真正指出。 谈话不是一个巨大的启示,而是我的两分钱。 谢谢

没有人完成共同表格expression (CTE)。 下面结合它和我使用的一些其他样式:

 @declare @tableVariable ( colA1 int, colA2 int, colB1 int, colB2 nvarchar(255), colB3 nvarchar(255), colB4 int, colB5 bit, computed int ); with getSomeData as ( select st.colA1, sot.colA2 from someTable st inner join someOtherTable sot on st.key = sot.key ), getSomeOtherData as ( select colB1, colB2, colB3, colB4, colB5, computed = case when colB5 = 1 then 'here' when colB5 = 2 then 'there' end from aThirdTable tt inner hash join aFourthTable ft on tt.key1 = ft.key2 and tt.key2 = ft.key2 and tt.key3 = ft.key3 ) insert @tableVariable ( colA1, colA2, colA2, colB1, colB2, colB3, colB4, colB5, computed ) select colA1, colA2, colB1, colB2, colB3, colB4, colB5, computed from getSomeData data1 join getSomeOtherData data2 

CTE格式的几点:

  • 在我的CTE中,“with”是分开的,而cte中的其他所有内容都是缩进的。
  • 我的CTE名字很长且具有描述性。 CTE可以变得复杂,描述性的名字是非常有用的。
  • 出于某种原因,我发现自己更喜欢用于CTE名称的动词。 使它看起来更加生动。
  • 类似的样式与Javascript的括号一样使用括号。 这也是我如何在C#中使用大括号。

这模拟:

 func getSomeData() { select st.colA1, sot.colA2 from someTable st inner join someOtherTable sot on st.key = sot.key } 

除CTE格式外还有几点:

  • “select”和其他关键字后的两个标签。 这为“内连接”,“分组依据”等留下了足够的空间。您可以在上面看到一个不正确的例子。 但是“内部散列连接”应该看起来很丑。 尽pipe如此,在这一点上我可能会尝试一下以上的一些风格。
  • 关键字是小写字母。 IDE的着色和它们特殊的缩进状态足以突出显示它们。 我根据本地(商业)逻辑为其他我想强调的东西保留大写字母。
  • 如果有几列,我把它们放在一行(getSomeData)。 如果还有更多,我将它们垂直(getSomeOtherData)。 如果在一个单元中有太多的垂直化,我将一些列按照本地定义的逻辑(最终的插入select段)分组到同一行中。 例如,我会把学校一级的资料放在一行,学生一级放在另一行上。
  • 特别是在垂直化时,我更喜欢sql server的“varname = colname + something syntax”到“colname + something varname”。
  • 加倍最后一点,如果我正在处理案件陈述。
  • 如果某种逻辑适合“matrix”风格,我将处理打字的后果。 这种情况说法就是这样,“whens”和“then”是一致的。

我发现我的CTE风格比其他领域更加稳定。 没有尝试过更类似于问题中提出的风格。 可能有一天会做,看看我喜欢它。 我可能会被诅咒在一个可以select的环境中,尽pipe这是一个有趣的诅咒。

我完全同意你的努力来标准化你的项目和一般的SQL格式。

我也非常赞同你的格式select。 我已经拿出了几乎相同的一个,除了我还缩进了“join”的陈述,并且与他们一起再次缩进了“陈述”。

非常类似于你在关键字上使用小写字母的事实 – 谁想要那些在你身上隐藏的东西。 我也喜欢小写字母表别名 – 使更好的可读性

非常像你使用小缩进(4)的事实。 我去(3)。

我认为“内部”和“外部”是不必要的。

这里是如何格式化你的select语句:

 select st.ColumnName1, jt.ColumnName2, sjt.ColumnName3 from SourceTable st join JoinTable jt on jt.SourceTableID = st.SourceTableID join SecondJoinTable sjt on st.SourceTableID = sjt.SourceTableID and jt.Column3 = sjt.Column4 where st.SourceTableID = X and jt.ColumnName3 = Y ; 

谢谢你讨论这个。

迟到总比不到好。 我使用了一种不同的风格,并从我曾经使用过的非常好的SQL开发人员那里采用了它。 我正确的alignment关键字,我使用不使用大写字母的轻松打字。 关键字将被编辑器突出显示,除非您在不支持关键字高亮function的文本编辑器中进行大量编辑,否则我不认为需要将它们放在大写字母中。 我不想尽量使它紧凑,但更可读性和尽可能垂直alignment。 这里是一个select从@BenLaan答案写在我的格式的例子:

 select st.ColumnName1 , jt.ColumnName2 , sjt.ColumnName3 from SourceTable st inner join JoinTable jt on jt.SourceTableID = st.SourceTableID inner join SecondJoinTable sjt on st.SourceTableID = sjt.SourceTableID and st.SourceTable2ID = sjt.SourceTable2ID where st.SourceTableID = X and jt.ColumnName3 = Y and jt.Column3 = sjt.Column4 order by st.ColumnName1 

试图使所有团队遵循相同的格式模式是最困难的事情。 如果其他人都以同样的方式进行,我会遵循任何格式,但从来没有这样的故事。

更新:重写前面提到的复杂查询之一:

 select term , student_id , case when((ft_credits > 0 and credits >= ft_credits) or (ft_hours_per_week > 3 and hours_per_week >= ft_hours_per_week)) then 'F' else 'P' end as status from (select term , student_id , pm.credits AS ft_credits , pm.hours AS ft_hours_per_week , SUM(credits) AS credits , SUM(hours_per_week) AS hours_per_week from (select e.term , e.student_id , nvl(o.credits, 0) credits , case when nvl(o.weeks, 0) > 5 then (nvl(o.lect_hours, 0) + nvl(o.lab_hours, 0) + nvl(o.ext_hours, 0)) / nvl(o.weeks, 0) else 0 end as hours_per_week from enrollment as e inner join offering as o using (term, offering_id) inner join program_enrollment as pe on e.student_id = pe.student_id and e.term = pe.term and e.offering_id = pe.offering_id where e.registration_code not in ('A7', 'D0', 'WL') ) inner join student_history as sh using (student_id) inner join program_major as pm on sh.major_code_1 = pm._major_code and sh.division_code_1 = pm.division_code where sh.eff_term = (select max(eff_term) from student_history as shi where sh.student_id = shi.student_id and shi.eff_term <= term) group by term, student_id, pm.credits, pm.hours ) order by term, student_id 

我喜欢我的SQL格式化,尽pipe只要意图易于阅读,大多数格式都可以工作。 我真的很讨厌查看在查询devise器中创build的语句,然后就这样离开了。 如果我正在编辑别人的程序/视图/函数/触发等,我会尽量保持已经使用的格式(除非真的不好,那么我会重新格式化整个事情)。

select声明

 SELECT ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 FROM SourceTable ST INNER JOIN JoinTable JT ON JT.SourceTableID = ST.SourceTableID INNER JOIN SecondJoinTable SJT ON ST.SourceTableID = SJT.SourceTableID AND JT.Column3 = SJT.Column4 WHERE (ST.SourceTableID = X) AND (JT.ColumnName3 = Y); 

更新声明

 UPDATE TargetTable SET ColumnName1 = @value, ColumnName2 = @value2 WHERE (Condition1 = @test); 

插入语句

 INSERT INTO TargetTable ( ColumnName1, ColumnName2, ColumnName3 ) values ( @value1, @value2, @value3 ); 

我认为有一个良好的格式规则是非常重要的,因为你可以很容易地发现和修复错误。 正如所说的 – “你正在写代码一次,这个代码被读取了1000万次”,所以总是花些时间在格式化上。 主要目标是:

  • 让你的代码更易于阅读和理解
  • 最大限度地减less维护或扩展代码所需的工作量
  • 减less系统用户和开发人员查阅二级文档资源(如代码注释或软件手册)的需求

我总是使用一些规则:

  • 总是使用。 符号
  • 在列之前总是使用别名,所以。 符号
  • 我把andor到行的末尾
  • 不要使用非英语的括号
  • 不要使用大写字母
  • 通常更喜欢cte嵌套子查询

作为一个例子,在这里我将如何格式化查询用作这个问题的一个例子:

 select ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 from <schema>.SourceTable as ST inner join <schema>.JoinTable as JT on ST.SourceTableID = JT.SourceTableID inner join <schema>.SecondJoinTable as SJT on SJT.SourceTableID = ST.SourceTableID and SJT.Column4 = JT.Column3 where ST.SourceTableID = X and JT.ColumnName3 = Y 

和“学生”查询:

 select term, student_id, case when (ft_credits > 0 and credits >= ft_credits) or (ft_hours_per_week > 3 and hours_per_week >= ft_hours_per_week) then 'F' else 'P' end as [status] from ( select a.term, a.student_id, pm.credits as ft_credits, pm.[hours] as ft_hours_per_week, sum(a.credits) as credits, sum(a.hours_per_week) as hours_per_week from ( select e.term, e.student_id, NVL(o.credits, 0) credits, case when NVL(o.weeks, 0) > 5 then (NVL(o.lect_hours, 0) + NVL(o.lab_hours, 0) + NVL(o.ext_hours, 0)) / NVL(o.weeks, 0) else 0 end as hours_per_week from enrollment as e inner join offering as o using (term, offering_id) inner join program_enrollment as pe on pe.student_id = e.student_id and pe.term = e.term and pe.offering_id = e.offering_id where e.registration_code Not in ('A7', 'D0', 'WL') ) as a inner join student_history as sh using (student_id) inner join program_major as pm on pm._major_code = sh.major_code_1 and pm.division_code = sh.division_code_1 where sh.eff_term = ( select max(eff_term) from student_history as shi where shi.student_id = sh.student_id and shi.eff_term <= term ) group by a.term, a.student_id, pm.credits, pm.[hours] ) as a order by term, student_id 

不同意见的数量是可怕的。 这是我的组织使用的:

  SELECT ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 FROM SourceTable ST INNER JOIN JoinTable JT ON JT.SourceTableID = ST.SourceTableID INNER JOIN SecondJoinTable SJT ON ST.SourceTableID = SJT.SourceTableID AND JT.Column3 = SJT.Column4 WHERE ST.SourceTableID = X AND JT.ColumnName3 = Y 

保持8个字符的缩进是可读性​​恕我直言的关键。

我喜欢的风格:

 SELECT ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 FROM SourceTable ST INNER JOIN JoinTable JT ON JT.SourceTableID = ST.SourceTableID INNER JOIN SecondJoinTable SJT ON ST.SourceTableID = SJT.SourceTableID WHERE ST.SourceTableID = X AND JT.ColumnName3 = Y AND JT.Column3 = SJT.Column4 
 SELECT st.ColumnName1 ,jt.ColumnName2 ,sjt.ColumnName3 FROM SourceTable st JOIN JoinTable jt ON jt.SourceTableID = st.SourceTableID JOIN SecondJoinTable sjt ON SstT.SourceTableID = sjt.SourceTableID AND jt.Column3 = sjt.Column4 WHERE st.SourceTableID = X AND jt.ColumnName3 = Y 

I use all caps for the actions words, joins or clauses, they stand out better. JOIN is the same as INNER JOIN so INNER does not need to be written out, it's assumed, write OUTER JOIN or LEFT JOIN when you need it. I also use lowere case for my alias names. Common out front cause if you comment out the last column you are stuck with a comma above and the query fails.

A hundred answers here already, but after much toing and froing over the years, this is what I've settled on:

 SELECT ST.ColumnName1 , JT.ColumnName2 , SJT.ColumnName3 FROM SourceTable ST JOIN JoinTable JT ON JT.SourceTableID = ST.SourceTableID JOIN SecondJoinTable SJT ON ST.SourceTableID = SJT.SourceTableID AND JT.Column3 = SJT.Column4 WHERE ST.SourceTableID = X AND JT.ColumnName3 = Y 

I know this can make for messy diffs as one extra table could cause me to re-indent many lines of code, but for my ease of reading I like it.

It appears that most of you still work on monitors that only support 800×600. My monitors will do 1920×1080, so I want to use up all that space to the right.

这个怎么样:

 select col1, col2, col3 , case when x = 1 then 'answer1' else 'answer2' end , col4, col5, col6, col7 from table1 t1 inner join table2 t2 on t1.col1 = t2.col1 and t1.col2 and t2.col2 where t1.col5 = 19 and t1.col7 = 'Bill Gates'