programing

SQL 형식화 표준

yoursource 2021. 1. 14. 23:24
반응형

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. 선택 라인의 의도는 레이아웃을 변경하지 않고 "상위 X"와 같은 다른 연산자를 허용하는 것입니다. 그 다음으로, 핵심 쿼리 요소 이후에 일관된 줄 바꿈을 유지하는 것만으로도 좋은 수준의 가독성을 얻을 수 있습니다.

fromand 뒤에 줄 바꿈을 삭제하면 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을 입력 할 때 갑자기 무작위로 이동할 수 있는지 항상 놀랍습니다.


소스 코드를 쉽게 읽을 수있는 한 형식화는 부차적이라고 생각합니다. 이 목표가 달성되는 한 채택 할 수있는 좋은 레이아웃 스타일이 많이 있습니다.

나에게 중요한 또 다른 측면은 상점에서 채택하기로 선택한 코딩 레이아웃 / 스타일이 모든 코더가 일관되게 사용하는지 확인하는 것입니다.

참고로 여기에 제공된 예제를 제시하는 방법이 있습니다. 특히이 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 사본을 받으십시오 . 원하는 레이아웃 기본 설정을 사용하도록 도구를 사용자 정의 할 수 있으며, 그러면 상점의 코더가 모두이 도구를 사용하여 모든 사람이 동일한 코딩 표준을 채택하도록 할 수 있습니다.


늦은 답변이지만 유용하기를 바랍니다.

대규모 개발 팀의 일원으로 일한 경험은 원하는 모든 표준을 계속해서 정의 할 수 있다는 것입니다.하지만 문제는 실제로 이러한 표준을 적용하거나 개발자가 쉽게 구현할 수 있도록 만드는 것입니다.

개발자로서 우리는 때때로 작동하는 무언가를 만들고 "나중에 포맷하겠습니다"라고 말하지만 나중에는 오지 않습니다.

처음에는이를 위해 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 색상이 더 좋음), 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하나 들여 비뚤어 또는 단어를 분할 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

이 혐오감은 학생이 주어진 기간에 풀 타임인지 파트 타임인지를 계산합니다. 스타일에 상관없이이 글은 읽기가 어렵습니다.


좋은. 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)에 들여 쓰기를 사용하면 괄호가 필요하지 않기 때문입니다. 따라서 들여 쓰기가 사용되는 경우 괄호는 레이아웃에 최소한의 영향을 미칩니다. 이것은 라인의 끝에 배치함으로써 달성됩니다.


John의 제안에 따라 다음 스타일을 제안합니다.

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

여기에있는 많은 예제보다 훨씬 더 많은 줄을 사용하지만 이해하기가 훨씬 쉽고 열 / 절 / 테이블을 빠르게 제거 할 수 있습니다. 수직 방향 모니터를 활용하는 데 도움이됩니다.


저는 오픈 소스 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

늦었지만 반지에 모자를 던질 게요. 작성하는 데 시간이 조금 더 걸리지 만 일단 익숙해지면 매우 읽기 쉽게 만드는 수직 정렬로 패턴이 나타납니다.

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
        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 column1
   ,column2
   ,column3
   ,column4
   ,Column5 ...ect

반대:

Select column1,
   column2,
   column3, ect...

내가이 방법을 선호하는 이유는 필요한 경우 줄을 주석 처리 할 수 ​​있고 해당 쉼표가 주석 처리되어 실행될 때 쉼표 문제가 발생하지 않기 때문입니다. 스레드에서이 작업을 수행했지만 실제로 지적하지 않은 다른 사용자를 보았다는 것을 알고 있습니다. 대화에 큰 폭로가 아니라 내 두 센트. 감사


ON조인과 같은 줄에 키워드를 입력 AND하고 OR줄 끝에 연산자를 입력하여 모든 조인 / 선택 기준이 잘 정렬되도록한다는 점을 제외하면 귀하와 유사한 형식을 사용합니다 .

내 스타일은 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문장, 나는 각각의 새로운 라인 들여 쓰기 줄 WHENELSE, 그리고 내가 정렬 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

I realise I am very late to this debate, but I would like to give my thoughts. I am definitely in favour of commas at the start of the line. Like you say Adam Ralph, it's easier to comment out a field and I also find it is more difficult to miss out a comma accidently when they are at the beginning, whilst this doesn't sound like a major issue. I have spent hours in the past trying to track down accidental syntax errors in lengthy T-SQL procedures, where I have accidently missed out a comma at the end of the line (I'm sure some of you have probably done this as well). I'm also in favour of aliasing as much as possible.

그러나 전반적으로 나는 그것이 모두 개인적인 취향에 달려 있다는 것을 알고 있으며, 어떤 사람들에게는 효과가있는 것이 다른 사람들에게는 그렇지 않다는 것을 알고 있습니다. 코드를 쉽게 읽을 수 있고 각 개발자가 전체적으로 자신의 스타일에서 일관성을 보여주는 한 그것이 가장 중요하다고 생각합니다.


이것은 내 개인 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())

아직 아무도 공통 테이블 식 (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 이름에 동사를 선호합니다. 더 생생하게 보입니다.
  • 자바 스크립트가 괄호로하는 것과 비슷한 스타일입니다. 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 서버의 "varname = colname + something syntax"를 "colname + something as varname"보다 선호합니다.
  • 케이스 진술을 처리하는 경우 마지막 포인트를 두 배로 늘리십시오.
  • 특정 로직이 '매트릭스'스타일에 적합하다면 타이핑 결과를 다룰 것입니다. 그것은 '언제'와 '그때'가 정렬되는 case 문에서 일어나는 일입니다.

나는 다른 영역보다 내 CTE 스타일에 더 잘 정착하고 있음을 발견했습니다. 질문에 제시된 것과 더 유사한 스타일을 실험하지 않았습니다. 아마도 언젠가는 내가 그것을 좋아하는지 볼 것입니다. 나는 선택의 여지가있는 환경에 있다는 저주를 받았을 것입니다.


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

내가 처음부터 글을 쓰고 있거나 관습이 없다면, 나는 키워드에 대문자를 사용하는 것을 선호하는 것을 제외하고는 질문에 주어진 관습을 따르는 경향이 있습니다 (가독성을위한 개인적인 선호).

다른 코드 형식 규칙과 마찬가지로 SQL 형식을 사용할 때 중요한 점은 규칙이 아닌 규칙을 갖는 것입니다 (물론 상식의 영역 내에서!)


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

내 애완 동물이 싫어하는 것은 테이블 접두사가 tbl이고 저장 프로 시저가 sp로 시작된다는 사실을 바탕으로 우리는 그것이 테이블과 SP라는 것을 압니다. DB 개체의 이름 지정은 얼마나 많은 공간이 있는지보다 훨씬 중요합니다.

내 0.02 달러 가치


SSMS 내에서 Red Gate SQL ReFactor를 사용하지만 재구성을 수행하는 (SSMS를 대체하는) 또 다른 도구는 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 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 가독성의 핵심입니다.


귀하의 프로젝트 내에서 그리고 일반적으로 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
;

논의 해 주셔서 감사합니다.


내 답변은에서 수락 한 답변과 유사합니다 John Sansom answered Feb 6 '09 at 11:05. 그러나 Red Gate의 SQL Prompt에 대한 답변과 달리 NOTEPAD ++에서 SQLInForm 플러그인을 사용하여 몇 가지 형식 지정 옵션을 보여줄 것입니다.

SQLInForm 플러그인에는 설정할 수있는 5 가지 프로필이 있습니다. 프로필에는 무료 및 유료 버전 모두에서 사용할 수있는 많은 설정이 있습니다. 전체 목록은 아래에 있으며 온라인에서 plugin-help-general-options 페이지를 볼 수 있습니다.

내 기본 설정에 대해 떠들썩하게하는 대신 사용 가능한 SQLInForm 옵션을 제시하는 것이 유용 할 것이라고 생각했습니다. 내 선호도 중 일부는 아래에 명시되어 있습니다. 내 게시물의 끝에는 원본 게시물 ( originalVS format1VS format2)에 사용 된 형식화 된 SQL 코드가 있습니다.

여기에서 다른 답변을 읽으십시오. 저는 몇 가지 부분에서 소수 인 것 같습니다. I like leading commas( Short Video Here )-IMO, 새 필드를 선택하면 훨씬 쉽게 읽을 수 있습니다. 또한 나는 Column1 with linebreakSELECT 옆이 아닌 나의 것을 좋아 합니다.


다음은 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. 키워드 (PRO)

[Upper / LowerCase]> 키워드

4. 줄 바꿈> 목록 (무료)

[쉼표 앞] = TRUE 5

[쉼표 2 열을 왼쪽으로 이동] = FALSE

5. 줄 바꿈> 선택 (PRO)

[JOIN> JOIN 후] = FALSE

[JOIN> ON 전] = FALSE

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

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

7. 줄 바꿈> 조건 (PRO)

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

8. 정렬 (PRO)

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

9. 공백 (PRO)

(변경?) 빈 줄  [모두 제거] = TRUE; [모두 유지]; [하나 유지]

10. 의견 (PRO)

(변경?) 줄 및 차단-> [블록 주석 앞 / 뒤 줄 바꿈] = TRUE; [줄 주석을 블록으로 변경]; [차단]

11. 저장된 Proc (PRO)

12. 고급 (PRO)

(유용 할 수 있음) 프로그램 코드에서 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

CONVERSION PREFERRED FORMAT (옵션 # 1 : JOIN no linebreak)

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

CONVERSION PREFERRED FORMAT (옵션 # 2 : JOIN with linebreak)

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 문

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

버그를 쉽게 발견하고 수정할 수 있기 때문에 좋은 서식 규칙을 갖는 것이 정말 중요하다고 생각합니다. 말했듯이- "한 번 코드를 작성하면이 코드는 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

내가 선호하는 스타일 :

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.


안하는 것보다 늦게하는 것이 낫다. 나는 다른 스타일을 사용하고 함께 일했던 아주 훌륭한 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

This is the format that I use. Please comment if it can be make better.

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

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

how about this:

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'

ReferenceURL : https://stackoverflow.com/questions/519876/sql-formatting-standards

반응형