私の最後の仕事では、データベースが非常に多いアプリケーションに取り組み、すべての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」などの他の演算子を許可することです。それに続いて、主要なクエリ要素の後に一貫したラインフィードを維持するだけで、読みやすさのレベルが高くなるように見えました。
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 /クエリアナライザーがSQLを書き出す方法とは大きく異なりませんが、do違います。
このトピックに関して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
1つのヒントとして、 SQLプロンプト のコピーを Red Gate から入手してください。希望のレイアウト設定を使用するようにツールをカスタマイズすると、ショップのコーダー全員がそれを使用して、全員が同じコーディング標準を採用できるようになります。
遅い答えですが、うまくいけば便利です。
大規模な開発チームの一員として働いている私の経験では、好きな標準を定義することができますが、実際にはこれらを強制するか、開発者が非常に簡単に実装できるようにすることが問題です。
開発者として、機能するものを作成して「後でフォーマットします」と言うこともありますが、それは後からありません。
最初は、このためにSQLプロンプトを使用しました(それは素晴らしかったです)が、無料ツールであるため 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は小文字の場合はより適切に色付けされます)、キャメルケースはありません(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
インデントの位置をずらすか、Word BY
を単独で分割します。 WHERE
句の述語全体をインデントする方が自然ですが、通常、次のAND
およびOR
演算子を左マージンに揃えます。ラップ後のインデントINNER JOIN
行も多少arbitrary意的です。
しかし、何らかの理由で、私はまだ他の方法よりも読みやすいと思います。
最後に、このフォーマットスタイルを使用した、より複雑な作品の1つで終わります。 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
の後の改行は、読みやすくするために必要な場合のみ。
コードがよりコンパクトで読みやすい場合、私は通常、よりコンパクトな形式を好みます。より多くのコードを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
最終的に、これはコードレビュー中に行われる判断の呼び出しになります。
insert
の場合、括弧を別の方法で配置します。
insert into TargetTable (
ColumnName1,
ColumnName2,
ColumnName3)
values (
@value1,
@value2,
@value3)
このフォーマットの理由は、SQLがブロック構造(Pythonなど)にインデントを使用した場合、括弧は必要ないためです。そのため、とにかくインデントが使用される場合、括弧はレイアウトに最小限の影響しか与えません。これは、行の最後に配置することにより実現されます。
私は、C#でオープンソースのSQL Formatter(この段階ではSQLサーバーのみ)の作成に取り組んでいるので、上記のクエリを使用します。
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
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
ここにある多くの例よりもはるかに多くの行を使用していますが、理解しやすく、列/句/表をすばやく削除できると感じています。これは、垂直指向のモニターを活用するのに役立ちます。
ジョンの提案に基づいて、次のスタイルを提案します。
/*
<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" -filterを追加すると、内部結合から左結合に変更する際の間違いを回避できます。
-改行にセミコロンを配置すると、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の宣言的な性質を考えると、最もクリーンで体系的なレイアウトが得られます。
おそらく、ここであらゆる種類の答えが見つかるでしょう。最終的には、個人的な好みまたはチームが同意した好みに依存します。
遅いですが、帽子をリングに投げます。書くのに少し時間がかかりますが、慣れるとパターンが非常に読みやすくなるため、垂直方向の配置でパターンが出現します。
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
これは私の個人的な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())
私はこの議論に非常に遅れていることに気づきましたが、考えを述べたいと思います。私は間違いなく、行頭のコンマを支持しています。 Adam Ralph と言うように、フィールドをコメントアウトするのは簡単です。また、最初にコンマを誤って見逃すことは難しいですが、これはメジャーのようには聞こえませんが問題。長い時間をかけて長いT-SQLプロシージャの偶発的な構文エラーを追跡しようとして過去何時間も費やしてきましたが、行末で誤ってコンマを忘れてしまいました(おそらくこれを行った人もいるでしょう) 。また、可能な限りエイリアシングを支持しています。
全体的に、しかし、私はそれがすべて個人的な好みに依存していることを理解しています。コードを簡単に読むことができ、各開発者がスタイル全体である程度の一貫性を示している限り、それが最も重要だと思います。
このスレッドには多くの良い点があります。私が人々に使用を説得しようと試みている1つの標準は、各列の前の同じ行にコンマを配置することです。そのようです:
Select column1
,column2
,column3
,column4
,Column5 ...ect
とは対照的に:
Select column1,
column2,
column3, ect...
私がこのプラクティスを好む理由は、必要に応じて行をコメントアウトでき、対応するコンマがコメントアウトされているために行を実行してもコンマの問題が発生しないためです。これを行ったスレッドで別のユーザーを見たことがありますが、実際には指摘していません。会話にもたらす大きな啓示ではなく、私の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形式に関するいくつかのポイント:
これはシミュレートします:
func getSomeData() {
select st.colA1, sot.colA2
from someTable st
inner join someOtherTable sot on st.key = sot.key
}
CTE形式以外のいくつかのポイント:
私は自分のCTEスタイルに他の分野よりも落ち着いていることがわかりました。質問で提示されたスタイルに似たスタイルを試していない。おそらくいつかやってみて、私はそれが好きかどうかを確認します。私はおそらく、それが選択できる環境にいるのは呪われていますが、それは楽しい呪いです。
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
ステートメントの場合、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
_
異なる意見の数は恐ろしいです。これは私の組織が使用するものです:
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文字のインデントを維持することが重要です。
プロジェクト内および一般的なSQLのフォーマットを標準化するためのあなたの努力に心から同意します。
また、フォーマットの選択にも非常に同意します。私は「join」ステートメントをインデントし、さらに「on」ステートメントをもう1インデントしない限り、ほぼ同じものを思い付きました。
キーワードに小文字を使用するという事実に非常によく似ています。小文字のテーブルエイリアスも好む-読みやすくする
小さなインデントを使用するという事実に非常によく似ています(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プロンプトでの答えとは対照的に、 NOTEPAD ++のSQLInFormプラグイン を使用して、いくつかのフォーマットオプションを示します。
SQLInFormプラグインには、セットアップ可能な5つの異なるプロファイルがあります。プロファイル内には、無料版と有料版の両方で利用可能な多くの設定があります。完全なリストは以下にあり、それらの plugin-help-general-options ページをオンラインで見ることができます。
私の好みをとりとめなくする代わりに、利用可能なSQLInFormオプションを提示することが有益だと考えました。私の好みのいくつかも以下に記載されています。投稿の最後に、元の投稿で使用されたフォーマット済みSQLコードがあります(original
VS format1
VS format2
)。
ここで他の答えを読んでください-私はいくつかのことで少数派のようです。好き leading commas
( Short Video Here )-IMO、新しいフィールドが選択されている場合、読みやすくなります。また、Column1 with linebreak
およびSELECTの隣ではありません。
SELECTステートメントを考慮した、いくつかの私の設定ノートの概要を以下に示します。 13のセクションすべてのスクリーンショットを追加します。しかし、それは多くのスクリーンショットであり、無料版をお勧めします。スクリーンショットをいくつか撮り、フォーマットコントロールをテストしてください。私はPro版をすぐにテストします。しかし、オプションに基づいて、それは本当に便利で、わずか20ドルであるように見えます。
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)
[結合>結合後] = FALSE
[JOIN> ON前] = FALSE
(変更なし)-> [JOIN> Indent JOIN]; [JOIN> ON後]
6。改行> Ins/Upd/Del(PRO)
7。改行>条件(PRO)
CASEステートメント-> [WHEN]、[THEN]、[ELSE]…確かにこれらの設定で遊んで、良い設定を選びたい
8。アライメント(PRO)
(変更なし)-> [JOIN> Indent JOIN]; [JOIN> ON後]
9。空白(PRO)
(変更?)空白行Blank [すべて削除] = TRUE; [すべて保ちます]; [キープワン]
10。コメント(PRO)
(変更?)行とブロック-> [ブロックコメントの前後の改行] = TRUE; [行コメントをブロックに変更]; [ラインにブロック]
11。ストアドプロシージャ(PRO)
12。高度な(PRO)
(役に立つかもしれません)プログラムコードからSQLを抽出-> [ExtractSQL]
13。ライセンス
元のクエリ形式。
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
お役に立てれば。
好き:
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
より小さな表示領域でより多くのコードを取得します。また、キーワードは大文字にする必要があります
SSMS内でRed Gate SQL ReFactorを使用していますが、再構成(およびSSMSの代替)を行う別のツールは ApexのSQL Edit です。オンラインでコードを投稿する場合は、 The Simple-Talk SQL Prettifier があります。
既に作成されたT-SQLに変更を加える場合、既に使用されている規則(ある場合)に従います。
私が最初から書いているか、慣例がない場合、キーワードに大文字を使用することを好むことを除いて、質問で与えられた慣習に従う傾向があります(読みやすさの個人的な好み)。
他のコード形式の規則と同様に、SQLの形式では、重要な点は、その規則が何であるかではなく、規則を持つことです(もちろん常識の範囲内!)
ええ、私はあなたのSQLを厳密に定義された方法でレイアウトすることの価値を見ることができますが、命名規則とあなたの意図は間違いなくもっと重要です。 10倍重要です。
それに基づいて、私のペット嫌いはtblが前に付いたテーブルであり、spが前に付いたストアドプロシージャです-それらはテーブルとSPであることがわかります。 DBオブジェクトの命名は、スペースの数よりもはるかに重要です
ちょうど私の$ 0.02相当
絶対に遅れるよりはましです。私は別のスタイルを使用し、以前使用していた非常に優れた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
すべてのチームが同じフォーマットパターンに従うようにすることは、最も難しいことです。誰もが同じ方法に従えば、私はどんなフォーマットでも従うでしょうが、それは同じ話ではありませんでした。
更新:以前の投稿で言及した複雑なクエリの1つを書き換えます。
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をそのようにフォーマットするのが好きですが、意図が読みやすい限り、ほとんどのフォーマットが機能します。クエリデザイナで作成されたステートメントを見るのが本当に嫌いです。他の人がプロシージャ/ビュー/関数/トリガーなどを編集している場合は、既に使用されているフォーマットを維持しようとします(本当に悪い場合を除き、全体を再フォーマットします)。
ステートメントを選択
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
を行末に配置します例として、ここでこの質問の例として使用されるクエリをどのようにフォーマットしますか:
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
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を書きます。また、エイリアス名には小文字を使用しています。最後の列をコメントアウトして、上のコンマでスタックし、クエリが失敗した場合の一般的な原因。
私の好みのスタイル:
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
これは私が使用する形式です。改善できる場合はコメントしてください。
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
ここではすでに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
余分なテーブルを1つ追加するとコードの多くの行がインデントされる可能性があるため、これにより面倒なdiffが作成される可能性がありますが、読みやすくするために気に入っています。