61

在我的上一份工作中,我们开发了一个非常依赖数据库的应用程序,并且我开发了一些格式标准,以便我们都可以使用通用布局编写 SQL。我们还开发了编码标准,但这些标准更特定于平台,所以我不会在这里讨论它们。

我很想知道其他人使用什么 SQL 格式化标准。与大多数其他编码环境不同,我还没有在网上为它们找到太多共识。

涵盖主要查询类型:

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。选择行的目的是允许其他操作符,例如“top X”而不改变布局。在此之后,在关键查询元素之后保持一致的换行似乎会产生良好的可读性。

from在and之后删除换行符where将是一个可以理解的修订。但是,在update下面的查询中,我们看到 之后的换行符where为我们提供了良好的列对齐。group by同样,在或之后的换行可以order by使我们的列布局清晰易读。

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

最后,一个insert

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

在大多数情况下,这些与 MS SQL Server Managements Studio / 查询分析器写出 SQL的方式相差不大,但是它们确实有所不同。

我期待着看看 Stack Overflow 社区是否就这个话题达成了共识。我一直惊讶于有多少开发人员可以遵循其他语言的标准格式,并且在使用 SQL 时突然变得如此随意。

4

28 回答 28

24

迟到的答案,但希望有用。

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

作为开发人员,我们有时会创建一些可行的东西,然后说“我稍后会格式化它”,但后来永远不会出现。

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

于 2013-05-12T05:58:46.747 回答
20

我认为,只要您可以轻松阅读源代码,格式是次要的。只要达到了这个目的,就有很多不错的布局风格可以采用。

对我来说唯一重要的另一个方面是,无论您选择在您的商店中采用何种编码布局/样式,请确保所有编码人员都始终如一地使用它。

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

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

一个提示,从Red Gate获取一份SQL Prompt副本。您可以自定义该工具以使用您想要的布局偏好,然后您商店中的编码员都可以使用它来确保每个人都采用相同的编码标准。

于 2009-02-06T11:05:33.947 回答
20

我迟到了,但我只会添加我喜欢的格式样式,我一定是从书籍和手册中学到的:它很紧凑。这是示例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 空格缩进,大写关键字(尽管 SO 在小写时颜色更好),没有驼峰(在 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 BY或者GROUP BY不对齐缩进,或者单独拆分单词BY。将子句的整个谓词缩进也会更自然WHERE,但我通常将跟随ANDOR运算符对齐在左边距。换行后的缩进INNER JOIN也有些随意。

但无论出于何种原因,我仍然发现它比其他选择更容易阅读。

我将使用这种格式样式完成我最近更复杂的创作之一。您在声明中遇到的几乎所有内容都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

这种可憎的计算方法是计算学生在给定学期内是全日制还是非全日制。不管风格如何,这个很难读。

于 2009-03-21T17:34:12.010 回答
7

迟到了,但我会把我的帽子扔进擂台。编写起来需要更长的时间,但我发现模式随着垂直对齐出现,一旦你习惯了它就变得非常可读。

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
于 2017-07-26T20:01:35.197 回答
6

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

之后的换行符selectfrom并且where仅在需要可读性时使用。

当代码可以更紧凑且同样可读时,我通常更喜欢更紧凑的形式。能够在一屏中容纳更多代码可以提高生产力。

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,我会以不同的方式放置括号:

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

这种格式的原因是,如果 SQL 对块结构使用缩进(如 Python),则不需要括号。因此,如果无论如何都使用缩进,那么括号对布局的影响应该最小。这是通过将它们放置在行尾来实现的。

于 2009-02-06T11:16:49.057 回答
6

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

它采用与 OP 类似的策略,即每个“部分”都有缩进的子元素。如果需要,我会在部分之间添加空白以帮助清晰——当没有连接或最小 where 条件时,不会添加这些空白。

结果:

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
于 2009-10-28T22:16:42.023 回答
6
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

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

于 2014-02-19T05:01:55.483 回答
4

根据约翰的建议,我建议采用以下风格:

/*
<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"-filters 可以避免从内连接更改为左连接时出现错误。
- 将分号放在换行符上可以轻松添加/注释 where 子句。

于 2015-01-20T13:02:31.603 回答
3

我倾向于使用与您类似的布局,尽管我什至更进一步,例如:

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 的声明性质,以这种方式使用制表提供了最干净、最系统的布局。

你可能会在这里得到各种各样的答案。最后,这取决于个人或团队同意的偏好。

于 2009-02-06T11:23:21.477 回答
2

我使用与您类似的格式,只是我将ON关键字放在与连接相同的行,并将ANDOR运算符放在行尾,以便我的所有连接/选择标准很好地排列。

虽然我的风格与 John Sansom 的风格相似,但我不同意将加入标准放在WHERE子句中。我认为它应该与连接表一起使用,以便它有条理且易于查找。

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

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语句,我为每个WHENand提供一个新行和缩进,并将后面ELSE对齐到:ENDCASE

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
于 2009-02-06T12:51:10.893 回答
2

不同意见的数量令人恐惧。这是我的组织使用的:

 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 个字符的缩进是可读性​​恕我直言的关键。

于 2015-11-20T19:22:00.517 回答
2

还没有人完成公用表表达式(CTE)。下面将它与我使用的其他一些样式结合在一起:

declare @tableVariable table (
    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 格式之外的几点:

  • “选择”和其他关键字之后的两个选项卡。这为“内部连接”、“分组依据”等留下了足够的空间。您可以在上面看到一个不正确的示例。但是“内部哈希连接”应该看起来很难看。尽管如此,在这一点上,我将来可能会尝试上述一些样式。
  • 关键字是小写的。IDE 对它们的着色及其特殊的缩进状态足以突出它们。我根据本地(业务)逻辑为要强调的其他内容保留大写字母。
  • 如果列数很少,我将它们放在一行(getSomeData)。如果还有更多,我将它们垂直化(getSomeOtherData)。如果一个单元中有太多垂直化,我会将一些列水平化到同一行中,并按本地定义的逻辑分组(最后的插入-选择段)。例如,我会将学校级别的信息放在一行上,将学生级别的信息放在另一行上,等等。
  • 特别是在垂直化时,我更喜欢 sql server 的“varname = colname + something 语法”而不是“colname + something as varname”。
  • 如果我正在处理案例陈述,请将最后一点加倍。
  • 如果某种逻辑适合“矩阵”风格,我将处理打字的后果。这就是 case 语句的情况,“whens”和“then”是对齐的。

我发现我比其他领域更确定我的 CTE 风格。没有尝试过与问题中提出的更相似的样式。可能有一天会做,看看我有多喜欢它。我可能被诅咒在一个可以选择的环境中,尽管这是一个有趣的诅咒。

于 2016-10-07T23:16:46.660 回答
1

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

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

我认为 SQL 格式与其他代码格式约定一样,重要的是要有一个约定,而不是那个约定(当然在常识范围内!)

于 2009-02-06T11:10:14.530 回答
1

是的,我可以看到以某种严格定义的方式布置你的 sql 的价值,但命名约定和你的意图肯定要重要得多。好像重要10倍。

基于此,我最讨厌以 tbl 为前缀的表和以 sp 为前缀的存储过程——我们知道它们是表和 SP。DB对象的命名远比有多少空格重要

只是我的 0.02 美元

于 2009-02-06T11:12:15.913 回答
1

我意识到我在这场辩论中已经很晚了,但我想谈谈我的想法。我绝对赞成在行首使用逗号。就像您说的Adam Ralph一样,注释掉一个字段更容易,而且我也发现在开头时意外遗漏逗号更困难,虽然这听起来不是一个主要问题。过去我花了几个小时试图在冗长的 T-SQL 过程中追踪意外的语法错误,我不小心漏掉了行尾的逗号(我相信你们中的一些人可能也这样做过) . 我也赞成尽可能多地使用别名。

不过,总的来说,我意识到这完全取决于个人喜好,对某些人有效的方法对其他人无效。只要您可以轻松阅读代码并且每个开发人员在整个过程中都表现出一定的风格一致性,我认为这是最重要的。

于 2009-09-08T08:45:54.340 回答
1

我喜欢:

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

在更小的查看区域中获取更多代码。我也相信关键字应该大写

于 2014-05-17T02:28:49.193 回答
1

我完全同意您在项目中和一般情况下标准化 SQL 格式的努力。

我也非常同意您的格式选择。我想出了几乎相同的一个,除了我还缩进了'join'语句,并且用它们'on'语句再缩进一个。

非常喜欢您在关键字上使用小写字母的事实 - 谁想要那些对您大喊大叫的人。我也更喜欢小写表格别名 - 提高可读性

非常类似于您使用小缩进 (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
;

感谢您讨论这个问题。

于 2014-11-13T20:36:11.970 回答
1

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

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

反对:

Select column1,
   column2,
   column3, ect...

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

于 2016-04-12T15:59:41.930 回答
1

这是我使用的格式。请评论是否可以做得更好。

CREATE PROCEDURE [dbo].[USP_GetAllPostBookmarksByUserId]
    @id INT,
    @startIndex INT,
    @endIndex INT
AS
BEGIN

    SET NOCOUNT ON

    SELECT      *
    FROM
            (   SELECT      ROW_NUMBER() OVER ( ORDER BY P.created_date ) AS row_num, P.post_id, P.title, P.points, p.estimated_read_time, P.view_count, COUNT(1) AS "total_attempts" -- todo
                FROM        [dbo].[BOOKMARKED] B
                INNER JOIN  [dbo].[POST] P
                ON          B.entity_id = P.post_id
                INNER JOIN  [dbo].[ATTEMPTED] A
                ON          A.entity_id = P.post_id
                WHERE       B.user_id = 1 AND P.is_active = 1
                GROUP BY    P.post_id, P.title, P.points, p.estimated_read_time, P.view_count
            )   AS PaginatedResult
    WHERE       row_num >= @startIndex
    AND         row_num < @endIndex
    ORDER BY    row_num

END
于 2018-08-08T07:51:22.070 回答
1

我的答案将类似于接受的答案John Sansom answered Feb 6 '09 at 11:05但是,我将在 NOTEPAD++ 中使用 SQLInForm 插件演示一些格式化选项,而不是他对 Red Gate 的 SQL Prompt 的回答。

SQLInForm 插件有 5 种不同的配置文件可供您设置。在配置文件中,免费和付费版本都有很多可用的设置。下面是一个详尽的列表,您可以在线查看他们的插件帮助常规选项页面。

我认为展示可用的 SQLInForm 选项会很有用,而不是漫无边际地谈论我的偏好。我的一些偏好也在下面注明。在我的帖子末尾是原始帖子中使用的格式化 SQL 代码(originalVS format1VS format2)。

在这里阅读其他答案-在几件事上我似乎是少数。我喜欢leading commas这里的短视频)--IMO,选择新字段时更容易阅读。而且我喜欢我的Column1 with linebreak而不是旁边的 SELECT。


以下是我的一些偏好说明的概述,考虑到 SELECT 语句。我会添加所有 13 个部分的屏幕截图;但这是很多截图,我只是鼓励你使用免费版——截取一些截图,并测试格式控制。我将很快测试 Pro 版;但根据选项,它看起来真的很有帮助,而且只需 20 美元。

SQLInForm Notepadd++:选项和首选项

1. 一般(免费)

DB:任何 SQL、DB2/UDB、Oracle、MSAccess、SQL Server、Sybase、MYSQL、PostgreSQL、Informix、Teradata、Netezza SQL

[智能缩进]= FALSE

2. 颜色(免费)

3.关键词(专业版)

[大写/小写]> 关键字

4.换行符>列表(免费)

[逗号前]=TRUE 5

[将逗号向左移动 2 列]= FALSE

5.换行>选择(专业版)

[加入> 加入后]= FALSE

[JOIN> ON 之前]= FALSE

(没有变化)--> [JOIN> Indent JOIN]; [加入>开启后]

6.换行符> Ins/Upd/Del (PRO)

7.换行>条件(PRO)

CASE Statement--> [WHEN], [THEN], [ELSE] ...当然想玩这些设置并选择一个好的

8. 对齐 (PRO)

(没有变化)--> [JOIN> Indent JOIN]; [加入>开启后]

9.空白(专业版)

(更改?)空白行 [全部删除]=TRUE;[保留全部]; [保留一个]

10. 评论(专业版)

(更改?) Line & Block--> [Linebreak Before/After Block Comments]=TRUE; [将行注释更改为块];[封锁成线]

11. 存储过程 (PRO)

12. 高级(专业版)

(可能有用)从程序代码中提取 SQL-> [ExtractSQL]

13. 执照


SQL 代码

原始查询格式。

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

转换首选格式(选项 #1:加入无换行符)

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

转换首选格式(选项 #2:使用换行符连接)

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

希望这可以帮助。

于 2018-10-24T17:34:02.793 回答
0

迟到总比不到好。我使用了一种不同的风格,并从我曾经合作过的一位非常优秀的 SQL 开发人员那里采用了它。我右对齐关键字,我不使用大写字母以便于输入。关键字将由编辑器突出显示,除非您在不支持关键字突出显示功能的文本编辑器中进行大量编辑,否则我认为它们不需要大写。我并没有试图让它紧凑,而是尽可能地更具可读性和垂直对齐。以下是从@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
于 2014-08-15T14:21:53.620 回答
0

我喜欢这样格式化我的 SQL,尽管只要意图易于阅读,大多数任何格式都可以使用。我真的很讨厌看到在查询设计器中创建的语句然后就这样离开了。如果我正在编辑其他人的程序/视图/函数/触发器等,我将尝试保持已经使用的格式(除非它真的很糟糕,那么我将重新格式化整个内容)。

选择语句

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
           );
于 2015-02-27T21:17:22.247 回答
0

我喜欢的风格:

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
于 2017-06-13T18:00:49.793 回答
0
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

我对动作词、连接词或从句使用全部大写,它们更突出。JOIN 和 INNER JOIN 一样,所以 INNER 不需要写出来,假设需要的时候写 OUTER JOIN 或 LEFT JOIN。我的别名也使用小写。如果您注释掉最后一列,您会遇到上面的逗号并且查询失败,这是常见的原因。

于 2017-06-14T20:22:42.803 回答
0

已经有一百个答案了,但经过多年的反复推敲,这就是我所决定的:

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

我知道这会造成混乱的差异,因为一个额外的表可能会导致我重新缩进许多代码行,但为了便于阅读,我喜欢它。

于 2017-11-16T16:39:40.887 回答
0

这是我个人的 SQL 风格指南。它基于其他几个,但有一些主要的风格特征 - 小写关键字,没有无关的关键字(例如outer, inner, asc)和“河流”。

示例 SQL 如下所示:

-- basic select example
select p.Name as ProductName
     , p.ProductNumber
     , pm.Name as ProductModelName
     , p.Color
     , p.ListPrice
  from Production.Product as p
  join Production.ProductModel as pm
    on p.ProductModelID = pm.ProductModelID
 where p.Color in ('Blue', 'Red')
   and p.ListPrice < 800.00
   and pm.Name like '%frame%'
 order by p.Name

-- basic insert example
insert into Sales.Currency (
    CurrencyCode
    ,Name
    ,ModifiedDate
)
values (
    'XBT'
    ,'Bitcoin'
    ,getutcdate()
)

-- basic update example
update p
   set p.ListPrice = p.ListPrice * 1.05
     , p.ModifiedDate = getutcdate()
  from Production.Product p
 where p.SellEndDate is null
   and p.SellStartDate is not null

-- basic delete example
delete cc
  from Sales.CreditCard cc
 where cc.ExpYear < '2003'
   and cc.ModifiedDate < dateadd(year, -1, getutcdate())
于 2018-12-18T22:27:57.797 回答
-1

我认为拥有良好的格式规则非常重要,因为您可以轻松发现和修复错误。正如它所说 - “你编写代码一次,这段代码被读取了 10000000 次”,所以花一些时间在格式化上总是好的。主要目标是:

  • 使您的代码更易于阅读和理解
  • 最大限度地减少维护或扩展代码所需的工作量
  • 减少系统用户和开发人员查阅代码注释或软件手册等辅助文档资源的需要

我经常使用的一些规则:

  • 始终使用 . 符号
  • 总是在列之前使用别名,所以 . 符号
  • 我把andandor放到了行尾
  • 不要使用不必要的括号
  • 不要使用大写
  • 通常更喜欢使用 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
于 2015-06-02T15:37:19.320 回答
-5

看来你们中的大多数人仍在使用仅支持 800x600 的显示器。我的显示器会做 1920x1080,所以我想用完右边的所有空间。

这个怎么样:

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'
于 2015-02-17T16:26:41.567 回答