programing

SQL 형식 표준

projobs 2023. 6. 23. 23:34
반응형

SQL 형식 표준

전 직장에서 우리는 매우 많은 데이터베이스를 필요로 하는 애플리케이션을 작업했고, 공통 레이아웃으로 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그리고.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/Query Analyzer가 SQL을 작성하는 방식에서 크게 벗어나지는 않지만 차이가 있습니다.

스택 오버플로 커뮤니티에서 이 주제에 대한 합의가 있는지 확인해 보기를 기대합니다.저는 얼마나 많은 개발자들이 다른 언어의 표준 포맷을 따를 수 있는지, 그리고 SQL을 칠 때 갑자기 그렇게 무작위로 될 수 있는지에 대해 항상 놀랐습니다.

답변이 늦었지만, 도움이 되길 바랍니다.

대규모 개발 팀의 일원으로 일한 경험은 여러분이 원하는 표준을 정의할 수 있다는 것입니다. 하지만 문제는 이러한 표준을 실제로 적용하거나 개발자들이 구현하기 쉽게 만드는 것입니다.

개발자로서 우리는 가끔 작동하는 것을 만들고 나서 "나중에 포맷할게"라고 말하지만, 나중에 그런 일은 결코 일어나지 않습니다.

처음에는 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칸 들여쓰기, 대문자로 된 키워드(소문자로 된 경우 SO 색상이 더 낫지만), 낙타 케이스(오라클의 경우 포인트 없음) 및 필요할 때 줄 바꿈.

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문이이문표니다됩시,. (그것은 또한 하기 위해 되었고, 했을 수도 .)(또한 기원을 위장하기 위해 변경되었으며, 제가 오류를 발생시켰을 수도 있습니다.)

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

이 혐오는 학생이 특정 학기에 정규 시간제인지 또는 시간제인지를 계산합니다.스타일에 상관없이, 이것은 읽기 어렵습니다.

소스 코드를 쉽게 읽을 수 있는 한 포맷은 2차적인 것이라고 생각합니다.이 목표가 달성되는 한, 채택할 수 있는 여러 가지 좋은 레이아웃 스타일이 있습니다.

제게 중요한 유일한 측면은 가게에서 어떤 코딩 레이아웃/스타일을 선택하든 모든 코딩자가 일관되게 사용해야 한다는 것입니다.

참고로, 제가 원하는 레이아웃과 함께 제공한 예제를 보여드리겠습니다.할 점은, 점은할목주특히,점은▁of,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 사본을 구입할 수 있습니다.원하는 레이아웃 기본 설정을 사용하도록 도구를 사용자 지정할 수 있습니다. 그러면 상점의 코더가 모두 이 도구를 사용하여 모든 사용자가 동일한 코딩 표준을 채택할 수 있습니다.

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,
       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

좋습니다. 파이썬 프로그래머로서 제가 선호하는 것은 다음과 같습니다.

후줄 바꿈이 뒤에 줄 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 등)에 들여쓰기를 사용했다면 괄호가 필요하지 않을 것이기 때문입니다.따라서 들여쓰기가 사용되는 경우에는 괄호가 레이아웃에 미치는 영향을 최소화해야 합니다.이 작업은 줄의 끝에 배치하여 수행됩니다.

저는 오픈소스 SQL Formatter(현재 SQL Server 전용)를 C#로 작성하는 작업을 하고 있어서 위와 같은 질문을 했습니다.

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

저는 존의 제안을 바탕으로 다음과 같은 스타일을 제안하고자 합니다.

/*
<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 절을 쉽게 추가/주석할 수 있습니다.

저는 당신과 비슷한 레이아웃을 사용하는 경향이 있습니다. 예를 들어, 몇 단계 더 나아가기도 합니다.

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

아마도 처음에는 약간 과장된 것처럼 보이지만 IMHO는 이러한 방식으로 표를 사용하면 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

8자 들여쓰기를 유지하는 것이 IMHO 가독성의 핵심입니다.

저는 당신과 비슷한 형식을 사용합니다. 단, 다음과 같은 형식을 사용합니다.ON과 같은 는 가과같은줄있는키워와제드가넣다니었습에입▁keyword다▁on니▁i▁put넣습▁as었.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:

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

아직 아무도 공통 테이블 표현(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).몇 개 더 있으면 세로로 표시합니다(Get SomeOtherData).한 단위에 너무 많은 수직화가 있는 경우 일부 열을 로컬로 정의된 논리(최종 삽입 선택 세그먼트)로 그룹화된 동일한 선으로 수평화합니다.예를 들어, 저는 학교 수준의 정보를 한 줄에, 학생 수준의 정보를 다른 줄에 배치할 것입니다.
  • 특히 세로쓰기를 할 때는 "colname + something as varname" 보다는 sql server의 "varname = colname + something 구문"을 선호합니다.
  • 내가 사건 진술을 처리할 때 마지막 점을 두 배로 늘립니다.
  • 특정 논리가 '매트릭스' 스타일에 적합하다면, 저는 타이핑 결과를 처리할 것입니다.그것이 '언제'와 '그때'가 정렬된 사례 진술에서 일어나고 있는 일입니다.

저는 다른 분야보다 CTE 스타일에 더 만족하고 있습니다.질문에 제시된 것과 더 유사한 스타일을 실험해 본 적이 없습니다.아마도 언젠가는 그렇게 할 것이고 내가 그것을 어떻게 좋아하는지 볼 것입니다.나는 아마도 그것이 선택인 환경에 있는 것이 저주받을 것입니다, 비록 그것이 가지는 재미있는 저주일지라도.

이미 작성된 T-SQL을 변경하는 경우 이미 사용된 규칙을 따릅니다(있는 경우).

만약 제가 처음부터 쓰고 있거나 관례가 없다면, 저는 키워드에 대문자를 사용하는 것을 선호한다는 것을 제외하고는 질문에 나온 당신의 관례를 따르는 경향이 있습니다(단, 저는 단지 가독성에 대한 개인적인 선호입니다.

다른 코드 형식 규칙과 마찬가지로 SQL 형식의 경우 중요한 점은 규칙이 무엇인지가 아니라 규칙을 갖는 것이라고 생각합니다(물론 상식의 영역 내에서!).

예, 엄격하게 정의된 방식으로 SQL을 배치하는 것의 가치는 알 수 있지만 명명 규칙과 의도가 훨씬 더 중요합니다.10배 더 중요한 것처럼.

내 애완동물이 싫어하는 것은 tbl로 접두사가 붙은 테이블과 sp로 접두사가 붙은 저장 프로시저라는 것을 바탕으로 우리는 그것들이 테이블과 SP라는 것을 알고 있습니다.DB 객체의 이름 지정은 공간 수보다 훨씬 더 중요합니다.

내 0.02달러어치만

좋아요:

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...

제가 이 연습을 선호하는 이유는 필요한 경우 한 줄을 주석 처리할 수 있고 해당 쉼표도 주석 처리되기 때문에 실행 시 쉼표 문제가 발생하지 않기 때문입니다.스레드에서 이 작업을 수행했지만 실제로는 지적하지 않은 다른 사용자를 본 것으로 알고 있습니다.대화를 이끌어내기 위한 큰 계시는 아니지만 제 2센트입니다.감사해요.

프로젝트 내에서 그리고 일반적으로 SQL 포맷을 표준화하려는 당신의 노력에 전적으로 동의합니다.

저는 또한 당신의 포맷 선택에 매우 동의합니다.저는 거의 같은 것을 생각해 냈지만, '가입' 문을 들여쓰기도 하고, '온' 문을 한 번 더 들여쓰기도 했습니다.

당신이 키워드에 대해 소문자를 선택한다는 사실과 매우 유사합니다 - 누가 당신에게 소리친 사람들을 원합니까?또한 대/소문자 표 별칭을 낮게 지정하여 가독성을 향상시킵니다.

작은 들여쓰기(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
;

이것에 대해 논의해 주셔서 감사합니다.

저는 제가 이 토론에 매우 늦었다는 것을 알지만, 저는 제 생각을 말하고 싶습니다.나는 분명히 줄의 시작 부분에 쉼표를 사용하는 것에 찬성합니다.아담 랄프의 처럼, 필드를 주석 처리하는 것이 더 쉽고 쉼표를 실수로 누락하는 것이 더 어렵다는 것을 알게 되었습니다. 하지만 이것은 큰 문제처럼 들리지 않습니다.저는 과거에 긴 T-SQL 절차에서 실수로 구문 오류를 추적하기 위해 몇 시간을 보냈습니다. 여기서 실수로 줄 끝에 있는 쉼표를 빠뜨린 적이 있습니다(여러분 중 일부도 이 작업을 수행했을 것입니다).저도 가능한 한 앨리어싱에 찬성합니다.

하지만, 전반적으로, 저는 그것이 모두 개인적 선호에 달려 있다는 것을 알고 있습니다, 어떤 사람들에게는 효과가 있는 것이 다른 사람들에게는 그렇지 않습니다.코드를 쉽게 읽을 수 있고 각 개발자들이 일관성 있게 일관성을 보이는 한, 그것이 가장 중요하다고 생각합니다.

이것이 제가 사용하는 형식입니다.더 나은 것이 될 수 있는지 댓글을 달아주세요.

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

제 답변은 다음과 같이 수락된 답변과 유사할 것입니다.John Sansom answered Feb 6 '09 at 11:05하지만 Red Gate에서 SQL Prompt를 사용한 답변과 달리 NAMEPOTE++에서 SQLInForm 플러그인을 사용한 몇 가지 포맷 옵션을 보여드리겠습니다.

SQLInForm 플러그인에는 설정할 수 있는 5가지 프로파일이 있습니다.프로필에는 무료 버전과 유료 버전 모두에서 사용할 수 있는 많은 설정이 있습니다.전체 목록은 아래에 있으며 플러그인 도움말 일반 옵션 페이지를 온라인으로 볼 수 있습니다.

제가 선호하는 것에 대해 횡설수설하는 대신 SQLInForm 옵션을 제시하는 것이 유용할 것이라고 생각했습니다.제가 선호하는 몇 가지 사항도 아래에 나와 있습니다.게시물에 (SQL Code)가 .original »format1 »format2).

다른 답변들을 읽어보면, 저는 몇 가지에 대해 소수인 것 같습니다.좋아해요leading commas(짧은 비디오 여기)-- IMO, 새 필드를 선택할 때 읽기가 훨씬 쉽습니다.그리고 또한 나는 나의 것을 좋아합니다.Column1 with linebreakSELECT 옆에 없습니다.


다음은 SELECT 문을 고려한 몇 가지 기본 설정 노트에 대한 개요입니다.저는 13개 섹션의 스크린샷을 모두 추가할 것입니다. 하지만 그것은 많은 스크린샷입니다. 저는 무료 에디션을 추천합니다. 스크린샷을 찍고 포맷 컨트롤을 테스트합니다.곧 Pro Edition을 테스트할 예정입니다. 하지만 옵션에 따르면 20달러면 정말 도움이 될 것 같습니다.

SQLInForm 메모장 추가 ++: 옵션 및 기본 설정

일반(무료)

DB: 모든 SQL, DB2/UDB, Oracle, MSAccess, SQL Server, Sybase, MYSQL, PostgreSQL, Informix, Teradata, Netezza SQL

[스마트 들여쓰기]= FALSE

색상(무료)

키워드(PRO)

[대/소문자 구분]> 키워드

줄 바꿈 > 목록(무료)

[콤마 전]=TRUE 5

[콤마 2개 콜을 왼쪽으로 이동]= FALSE

줄 바꿈>선택(PRO)

[JOIN > JOIN 후]= FALSE

[JOIN> ON 전]= FALSE

(변경사항 없음)--> [JOIN > JOIN 들여쓰기];[JOIN > ON 후]

줄 바꿈 > Ins/Upd/Del(PRO)

줄 바꿈 > 조건(PRO)

사례 설명--> [WHEN], [THEN], [ELSE] … 확실히 이러한 설정을 사용하여 좋은 설정을 선택하고 싶습니다.

선형(PRO)

(변경사항 없음)--> [JOIN > JOIN 들여쓰기];[JOIN > ON 후]

공백(PRO)

(변경?)빈 줄  [모두 제거]=참; [모두 보관]; [하나 보관]

댓글(PRO)

(변경?)Line & Block--> [블럭 댓글 전/후 라인브레이크]=참; [라인 주석을 블록으로 변경]; [라인으로 차단]

저장된 Proc(PRO)

고급(PRO)

(도움이 될 수 있음) 프로그램 코드에서 SQL 추출--> [추출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

변환 기본 형식(옵션 #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

이게 도움이 되길 바랍니다.

나는 내 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
           );

내가 선호하는 스타일:

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

저는 액션 단어, 결합 또는 절에 모든 캡을 사용합니다. 그것들은 더 두드러집니다.JOIN은 INER JOIN과 동일하므로 INER를 기재할 필요가 없으며, 필요할 때 OUTER JOIN 또는 LEFT JOIN을 작성해야 합니다.저는 또한 별칭 이름에 소문자를 사용합니다.일반적인 외부 원인은 마지막 열을 주석 처리할 경우 위의 쉼표로 고정되어 쿼리가 실패합니다.

이미 여기에 100개의 답이 있지만, 수년간 많은 장난을 치다가, 이것이 제가 결정한 것입니다.

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 개발자로부터 그것을 채택했습니다.키워드를 오른쪽 정렬하고 입력하기 쉽도록 대문자를 사용하지 않습니다.키워드는 편집기에 의해 강조 표시되며 키워드 강조 표시 기능을 지원하지 않는 텍스트 편집기에서 많은 편집을 하지 않는 한 대문자로 표시할 필요가 없습니다.컴팩트하게 하려고 하는 것이 아니라, 가능한 한 읽기 쉽고 수직으로 정렬하려고 합니다.다음은 제 형식으로 작성된 @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 스타일 가이드입니다.다른 몇 가지를 기반으로 하지만 소문자 키워드, 외부 키워드(예: 없음)와 같은 몇 가지 주요 스타일 기능이 있습니다.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())

버그를 쉽게 발견하고 수정할 수 있기 때문에 좋은 포맷 규칙을 갖는 것이 정말 중요하다고 생각합니다."코드를 한 번 쓰면 10000000번 읽힌다"는 말이 있듯이 포맷에 시간을 할애하는 것이 항상 좋습니다.주요 목표는 다음과 같습니다.

  • 코드를 더 쉽게 읽고 이해할 수 있도록 설정
  • 코드를 유지하거나 확장하는 데 필요한 작업 최소화
  • 시스템 사용자와 개발자가 코드 주석 또는 소프트웨어 설명서와 같은 보조 문서 소스를 참조할 필요성 감소

항상 사용하는 몇 가지 규칙:

  • 항상 . 표기법을 사용합니다.
  • 열 앞에는 항상 별칭을 사용하므로 . 표기법
  • 내가 넣었습니다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

여러분 대부분은 여전히 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'

언급URL : https://stackoverflow.com/questions/519876/sql-formatting-standards

반응형