代码之家  ›  专栏  ›  技术社区  ›  Timbo

SQL格式标准

  •  51
  • Timbo  · 技术社区  · 17 年前

    在我的上一份工作中,我们开发了一个非常依赖数据库的应用程序,我开发了一些格式化标准,这样我们就可以用一个通用的布局编写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”)在不改变布局的情况下进行操作。在此基础上,简单地在关键查询元素之后保持一致的换行符似乎可以带来良好的可读性。

    将换行符放在 从…起 哪里 这将是一个可以理解的修订。但是,在诸如 update 下面,我们可以看到在 哪里 为我们提供了良好的列对齐。类似地,后面的换行符 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
    )
    

    在大多数情况下,这些都没有偏离微软的方式那么远 SQL Server Managements Studio /查询分析器写出SQL,但是 做 相异

    我期待着看到Stack Overflow社区在这个话题上是否有任何共识。我经常感到惊讶的是,有多少开发人员能够遵循其他语言的标准格式,在使用SQL时突然变得如此随意。

    29 回复  |  直到 8 年前
        1
  •  24
  •   Sae1962    8 年前

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

    作为开发人员,我们有时会创建一些有用的东西,然后说稍后将对其进行格式化,但以后再也不会出现这种情况。

    最初,我们使用了SQL提示符(非常好),但后来切换到 ApexSQL Refactor ,因为这是一个免费的工具。

        2
  •  20
  •   Sae1962    8 年前

    我的观点是,只要你能很容易地阅读源代码,格式是次要的。只要实现这一目标,就可以采用许多良好的布局样式。

    仅供参考,以下是我将如何介绍您提供的示例,只是我的布局偏好。特别值得注意的是 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
    

    一个提示,给自己一份 SQL Prompt 从…起 Red Gate . 您可以自定义工具以使用所需的布局首选项,然后您商店中的编码人员都可以使用它来确保每个人都采用相同的编码标准。

        3
  •  19
  •   yukondude    17 年前

    我来晚了,但我只想添加我喜欢的格式样式,我一定是从书本和手册中学到的:它很紧凑。这是样品 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
    

    这个 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 子句,但我通常将以下内容对齐 AND 和 OR 运算符位于左边距。包装后缩进 INNER JOIN 线条也有点随意。

    但不管出于什么原因,我仍然觉得它比其他选择更容易阅读。

    最后,我将使用这种格式样式完成我最近的一个更复杂的创作。几乎所有你在一次旅行中遇到的事情 选择 语句出现在这一个。(它也被修改以掩盖其起源,我可能在这样做时引入了错误。)

    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
    

        4
  •  7
  •   Error_2646    9 年前

    迟到了,但我要参加比赛。写起来要花更长的时间,但我发现垂直对齐的模式会出现,一旦你习惯了,它就会变得非常可读。

    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
    
        5
  •  6
  •   Sae1962    8 年前

    美好的作为Python程序员,以下是我的首选项:

    select , from 和 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),则不需要括号。因此,如果使用缩进,则括号对布局的影响最小。这是通过将它们放置在行的末尾来实现的。

        6
  •  6
  •   Sae1962    8 年前
    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
    

        7
  •  6
  •   Sae1962    8 年前

    我正在用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
    
        8
  •  4
  •   Wouter BoltClock    11 年前

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

    /*
    <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
            )
    ;
    

    优势:
    -注释是使代码可读和检测错误的重要部分。

    -将分号放在换行符上可以方便地添加/注释where子句。

        9
  •  3
  •   Sae1962    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
    

    也许一开始它看起来有点过头了,但鉴于SQL的声明性,以这种方式使用表格给出了最干净、最系统的布局。

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

        10
  •  2
  •   dthree    10 年前

     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个字符的缩进是IMHO可读性的关键。

        11
  •  2
  •   Sae1962    8 年前

    ON 关键字与连接在同一行,我将 AND 和 OR

    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 语句中,我为每个语句指定一个新行和缩进 WHEN 和 ELSE ,然后我将 END 回到 案例 :

    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
    
        12
  •  2
  •   pwilcox    7 年前

    common table expressions (CTEs)还没有。下面将其与我使用的其他一些样式合并:

    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可以得到复杂的描述性名称,这非常有用。
    • 使用括号的样式类似于Javascript使用大括号的样式。这也是我用C#做大括号的方法。

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

    除了CTE格式之外,还有几点:

    • “选择”和其他关键字后的两个选项卡。这就为“内部连接”、“分组方式”等留出了足够的空间。您可以看到上面的一个例子,但事实并非如此。但是“内部散列连接”应该看起来很难看。然而,在这一点上,我可能会在未来尝试上面的一些风格。
    • 如果列很少,我将它们放在一行(getSomeData)。如果还有一些,我将它们垂直化(获取其他数据)。如果在一个单元中有太多的垂直化,我将一些列水平化到同一行中,按本地定义的逻辑分组(最后的插入选择段)。例如,我会把学校级别的信息放在一行上,把学生级别的信息放在另一行上,等等。
    • 特别是在垂直化时,我更喜欢sql server的“varname=colname+something语法”而不是“colname+something as varname”。
    • 如果我在处理一个案件陈述的话,把最后一点加倍。
    • 如果某个逻辑适合于“矩阵”样式,我将处理键入结果。case语句就是这样的,when和then是对齐的。

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

        13
  •  1
  •   Russ Cam    17 年前

    如果我是白手起家或者没有约定,那么我倾向于遵循你在问题中给出的约定,除了我更喜欢用大写字母作为关键词(只是个人对可读性的偏好)。

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

        14
  •  1
  •   MrTelly    17 年前

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

    只有我的0.02美元价值

        15
  •  1
  •   user1400745    12 年前

    我喜欢:

    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
    

    在较小的查看区域中获取更多代码。

        16
  •  1
  •   AeternusMenti    10 年前

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

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

    反对:

    Select column1,
       column2,
       column3, ect...
    

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

        17
  •  1
  •   dlink    9 年前

    我完全同意您在项目中和总体上标准化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
    ;
    

        18
  •  1
  •   Sae1962    8 年前

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

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

        19
  •  1
  •   CodeZila    8 年前

    请评论是否可以做得更好。

    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
    
        20
  •  1
  •   SherlockSpreadsheets    8 年前

    我的答案将与 John Sansom answered Feb 6 '09 at 11:05 . 但是,我将使用 SQLInForm plugin in NOTEPAD++ ,而不是他用红门的SQL提示符回答。

    plugin-help-general-options 网页在线。

    我认为展示可用的SQLInForm选项会很有用,而不是漫无目的地谈论我的偏好。下面还列出了我的一些偏好。在我文章的末尾是原始文章中使用的格式化SQL代码( original VS format1 VS format2 ).

    leading commas ( Short Video Here )--在我看来,当选择一个新字段时,阅读起来要容易得多。我也喜欢我的工作 Column1 with linebreak 而不是在“选择”旁边。


    下面是我的一些偏好注释的概述,考虑到SELECT语句。我会添加所有13个部分的截图;但是这有很多截图,我鼓励你使用免费版——截图,测试格式控制。我将很快测试专业版;但从选项来看,它看起来真的很有用,而且只需20美元。

    1.一般(免费)

    DB:任何SQL、DB2/UDB、Oracle、MSAccess、SQL Server、Sybase、MYSQL、,

    [智能缩进]=错误

    [大写/小写]>关键词

    [JOIN>在JOIN之后]=FALSE

    [JOIN>Before ON]=FALSE

    (不变)——>[JOIN>缩进连接];[在之后加入>]

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

    7.换行符>条件(专业)

    使用这些设置并选择一个好的

    8.校准(PRO)

    9空格(PRO)

    (更改?)空行[删除所有]=真;[保留所有];[留一个]

    10评论(专业版)

    (更改?)线路和;块-->[块前/块后换行符] 注释]=正确;[将行注释更改为块];[排成一行]

    12高级(专业)

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

    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
    

    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
    

    希望这有帮助。

        21
  •  0
  •   Larry G    11 年前

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

    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
               );
    
        22
  •  0
  •   Brady Holt    9 年前

    我喜欢的风格:

    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
    
        23
  •  0
  •   DanTheMan    9 年前
    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
    

    我用所有的大写来表示动作词、连接词或从句,它们更突出。连接与内部连接相同,因此内部连接不需要写出来,假设在需要时写外部连接或左连接。我的别名也使用小写字母。前面常见的原因如果注释掉最后一列,则上面会出现逗号,查询失败。

        24
  •  0
  •   Codemonkey    8 年前

    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
    

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

        25
  •  0
  •   Sae1962    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
             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
    
        26
  •  0
  •   mattmc3    7 年前

    This is my personal SQL style guide . 它是基于其他几个,但有几个主要的风格特征-小写的关键字,没有无关的关键字(例如。 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())
    
        27
  •  -1
  •   Jonathan Leffler    5 年前

    • 使您的代码更易于阅读和理解
    • 尽可能减少维护或扩展代码所需的工作量
    • 减少系统用户和开发人员查阅辅助文档源(如代码注释或软件手册)的需要

    • 始终使用。符号
    • 在列之前始终使用别名,以便。符号
    • 我把 and 和 or 排到最后
    • 不要使用不必要的括号
    • 通常更喜欢使用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
    
        28
  •  -5
  •   Bill J Blender    11 年前

    看来你们中的大多数人仍在使用仅支持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'