Slide 1

Slide 1 text

SQLFluffのルール一覧 jimatomo

Slide 2

Slide 2 text

本資料について SQLFluffのルールに関してまとめたものである。(非公式) バージョンは2.3.0をベースにしているので最新のものと差分がある可能性がある。 わかりやすさのために実際の例を書いていたりするか方言によっては異なる場合がある。 【目的】 SQLは分析基盤において中心になっているものです。(BIツールなどで使わなくても何とかなることもありますが、まだまだ必要な 場面も多い…) 一方で、コーディングルールの派閥が独自の進化を遂げていて、どれに統一したものか、そもそもコーディングルール を覚えきることができるのかと悩みも多いです。特にデータエンジニアの手から離れてデータ基盤の民主化を進めて いく中でコーディングルールを守ってもらうのはかなり難易度の高いものになっていくことでしょう。 そこで、一定のルールをもとに自動でチェックしてくれるSQLFluffのLinterの力が必要になってくると思います。この 資料を通してSQLFluffのルールの理解の助けになり、より多くのきれいなSQLが生まれればいいなと思います。 (一部の製品は生成系のAIの力を借りてSQLを生成する時代になりつつあるので、そういうものも含めてコーディングルールがカオスになりが ちな世の中になってきていると思いますのでこれからもっと必要になるはず) 2023/09/08 2

Slide 3

Slide 3 text

よく使われる用語 2023/09/08 3 用語 説明 dialect SQLにおける方言。RDBMSごとにANSIに準拠しない、独自の構文(方言)があるので、利用しているRDBMSのことを指していると捉えていい。 keyword 予約語(Reserved Keyword)といった方が正しい。SELECTやENDとか構文の中で利用される単語。 CTE 共通テーブル式(Common Table Expression)というWITH句を利用してサブクエリを切り出す記法のこと。

Slide 4

Slide 4 text

Aliasing (エイリアスの利用)

Slide 5

Slide 5 text

Anti-pattern Best Practice ルールの属性 設定値 【AL01】 テーブルのエイリアスの前には明示的にASを付与するべし テーブルのエイリアスの前にASをつけるように統一するべき 2023/09/08 5 SELECT a FROM foo zoo SELECT voo.a FROM foo AS voo Aliasing Code Alias Name description Groups sqlfluff fix compatible all core その他 AL01 L011 aliasing.table テーブルのエイリアスの前にASを付与するかど うか 〇 ー aliasing 〇 Name description default values aliasing 明示的なエイリアスが必要かどうか explicit explicit:エイリアス(AS)を明示的に付与する implicit:エイリアスを明示的に付与せず暗黙的にする

Slide 6

Slide 6 text

Anti-pattern Best Practice ルールの属性 設定値 【AL02】 カラムのエイリアスの前には明示的にASを付与するべし カラムのエイリアスの前にASをつけるように統一するべき 2023/09/08 6 SELECT a alias_col FROM foo SELECT a AS alias_col FROM foo Aliasing Code Alias Name description Groups sqlfluff fix compatible all core その他 AL02 L012 aliasing.column カラムのエイリアスの前にASを付与するかどう か 〇 〇 aliasing 〇 Name description default values aliasing 明示的なエイリアスが必要かどうか explicit explicit:エイリアス(AS)を明示的に付与する implicit:エイリアスを明示的に付与せず暗黙的にする

Slide 7

Slide 7 text

Anti-pattern Best Practice ルールの属性 設定値 【AL03】 カラム式には明示的にASと一緒にエイリアスを付与するべし 式だけだとよくないことがあるのでエイリアスを明示的に付与する。付与するときはASを付けるべき。 2023/09/08 7 SELECT sum(a), sum(b) FROM foo SELECT sum(a) AS a_sum, sum(b) AS b_sum FROM foo Aliasing Code Alias Name description Groups sqlfluff fix compatible all core その他 AL03 L013 aliasing.expression カラム式にASと一緒にエイリアスを付与する 〇 〇 aliasing ー Name description default values allow_scalar select句のカラムが単一の場合にエイリアスを 付けないことを許可するかどうか。 True True:select句のカラムが単一の場合はルールが無視される False:どんな時もエイリアスをつけるようにする

Slide 8

Slide 8 text

Anti-pattern Best Practice ルールの属性 設定値 【AL04】 エイリアスはユニークであるべし(名前が被らないようにするべし) テーブルエイリアスを使いまわすのはコーディングエラーでしょ! 2023/09/08 8 SELECT t.a, t.b FROM foo AS t, bar AS t SELECT f.a, b.b FROM foo AS f, bar AS b Aliasing Code Alias Name description Groups sqlfluff fix compatible all core その他 AL04 L020 aliasing.unique.table テーブルエイリアスがユニークであるかどうか 〇 〇 aliasing, aliasing.unique ー Name description default values ー

Slide 9

Slide 9 text

Anti-pattern Best Practice ルールの属性 設定値 【AL05】 エイリアスが利用されていない場合は使うべからず エイリアスが使われていないのに定義されているのは可読性の低下を招くだけなので利用しない。 2023/09/08 9 SELECT a FROM foo AS zoo SELECT a FROM foo Aliasing Code Alias Name description Groups sqlfluff fix compatible all core その他 AL05 L025 aliasing.unused テーブルエイリアスが利用されていない場合は エイリアスを削除する 〇 〇 aliasing 〇 Name description default values ー

Slide 10

Slide 10 text

Anti-pattern Best Practice ルールの属性 設定値 【AL06】 エイリアスの長さは適切なものにするべし エイリアスの文字列は極端に短くてもよくないので、ある程度の長さを強制することができる(テーブルエイリアスを使わない流派もあるくらい) 2023/09/08 10 SELECT SUM(o.amount) as order_amount FROM orders as o SELECT SUM(orders.amount) as order_amount FROM orders Aliasing Code Alias Name description Groups sqlfluff fix compatible all core その他 AL06 L066 aliasing.length From句とJOIN句の中で設定するテーブル のエイリアスの長さを強制する 〇 〇 aliasing ー Name description default values max_alias_length 許容されるエイリアスの最大長 NONE (0~1000) min_alias_length 許容されるエイリアスの最小長 NONE (0~1000)

Slide 11

Slide 11 text

Anti-pattern Best Practice ルールの属性 設定値 【AL07】 テーブルエイリアスは利用するべからず テーブルエイリアスのアンチ流派はこのルールを利用するといいですね(dbt style guideとかはjoinの中であまり使わないほうがいいと言っている) 2023/09/08 11 SELECT COUNT(o.customer_id) as order_amount, c.name FROM orders as o JOIN customers as c on o.id = c.user_id SELECT COUNT(orders.customer_id) as order_amount, customers.name FROM orders JOIN customers on orders.id = customers.user_id Aliasing Code Alias Name description Groups sqlfluff fix compatible all core その他 AL07 L031 aliasing.forbid テーブルのエイリアスを許容するかどうか 〇 ー aliasing ー Name description default values force_enable このルールがデフォルトで無効になっている dialectでも、このルールを実行する。(基本 的に全てのdialectで有効) False False:デフォルトが無効になっているdialectではルールを実行しない Ture:デフォルトが無効になっているdialectでもルールを実行する 議論の余地があるルールである。 特にBigQueryユーザは無効化のままを推奨

Slide 12

Slide 12 text

Anti-pattern Best Practice ルールの属性 設定値 【AL08】 カラムエイリアスはユニークであるべし カラムエイリアスが重複しているのは大体コーディングエラーでしょ!(””で囲っても大文字小文字も区別しません) 2023/09/08 12 SELECT a as foo, b as foo FROM tbl SELECT a as foo, b as bar FROM tbl Aliasing Code Alias Name description Groups sqlfluff fix compatible all core その他 AL08 ー aliasing.unique.column カラムエイリアスがユニークであるかどうか 〇 〇 aliasing, aliasing.unique ー Name description default values ー ※v2.3.0から導入

Slide 13

Slide 13 text

Ambiguous (あいまいな・多義的な表現の回避)

Slide 14

Slide 14 text

Anti-pattern Best Practice ルールの属性 設定値 【AM01】 GROUP BY句があるときはDISTINCTは使うべからず GROUP BY句があるときはDISTINCTは不要。(SELECT句に含むカラムはGROUP BYに含まれないといけないから) 2023/09/08 14 SELECT DISTINCT a FROM foo GROUP BY a SELECT a FROM foo GROUP BY a Ambiguous Code Alias Name description Groups sqlfluff fix compatible all core その他 AM01 L021 ambiguous.distinct GROUP BY句がある場合はDISTINCTを 削除する 〇 〇 ambiguous ー Name description default values ー

Slide 15

Slide 15 text

Anti-pattern Best Practice ルールの属性 設定値 【AM02】 単なるUNIONではなくUNION [DISTINCT|ALL]を利用すべし UNION DISTINCTしかサポートされていない場合はUNIONのみしかかけないけど、省略するとDISTINCTの場合はちゃんと区別しよう 2023/09/08 15 SELECT a, b FROM table_1 UNION SELECT a, b FROM table_2 SELECT a, b FROM table_1 UNION DISTINCT SELECT a, b FROM table_2 Ambiguous Code Alias Name description Groups sqlfluff fix compatible all core その他 AM02 L033 ambiguous.union UNION DISTINCTを明示的に記載する かどうか 〇 〇 ambiguous 〇 Name description default values ー

Slide 16

Slide 16 text

Anti-pattern Best Practice ルールの属性 設定値 【AM03】 ORDER BY句の中の中では明示的にASCを書くべし ASCかDESCはすべてのカラムに明示的に書いたほうがいいです 2023/09/08 16 SELECT a, b FROM foo ORDER BY a, b DESC SELECT a, b FROM foo ORDER BY a ASC, b DESC Ambiguous Code Alias Name description Groups sqlfluff fix compatible all core その他 AM03 L037 ambiguous.order_by ORDER BY句の中でASCを明示的に書く かどうか 〇 ー ambiguous 〇 Name description default values ー

Slide 17

Slide 17 text

Anti-pattern Best Practice ルールの属性 設定値 【AM04】 SELECT * は使うべからず *を使うと、上流テーブルで起きた変更の影響でSQLの結果が変わってしまうことがあるので注意が必要。(どこかで明示的に書けば、使ってもいい) 2023/09/08 17 WITH cte AS ( SELECT * FROM foo ) SELECT * FROM cte UNION SELECT a, b FROM t WITH cte AS ( SELECT a, b FROM foo ) SELECT * FROM cte UNION SELECT a, b FROM t Ambiguous Code Alias Name description Groups sqlfluff fix compatible all core その他 AM04 L044 ambiguous.column_count * を許容するかどうか 〇 ー ambiguous ー Name description default values ー

Slide 18

Slide 18 text

Anti-pattern Best Practice ルールの属性 設定値 【AM05】 INNER JOINも明示的に書くべし INNER JOINが単にJOINと書いた場合の動作になるが、明示的に書いておくほうが好ましい場合がある(これは好みの分かれそうなところ) 2023/09/08 18 SELECT foo FROM bar JOIN baz SELECT foo FROM bar INNER JOIN baz Ambiguous Code Alias Name description Groups sqlfluff fix compatible all core その他 AM05 L051 ambiguous.join JOINの種類を明示的に記載するかどうか 〇 ー ambiguous 〇 Name description default values fully_qualify_j oin_types INNER JOINのみ明示的に書く対象にする か、OUTERのみか、両方か指定する inner inner:INNER JOINのみLintの対象(実質変更不要) outer:OUTER JOINのみLintの対象(意味あるのか…?) both:両方Lintの対象

Slide 19

Slide 19 text

Anti-pattern Best Practice ルールの属性 設定値 【AM06】 GROUP BY, ORDER BY の中でのカラム参照形式は統一すべし dbt style guide的にはカラムの参照は 1, 2, 3, 4 とかが推奨されています。(WINDOW節はこのルールでは無視される) 2023/09/08 19 SELECT foo, bar, sum(baz) AS sum_value FROM fake_table GROUP BY foo, 2; SELECT foo, bar, sum(baz) AS sum_value FROM fake_table GROUP BY 1, 2; Ambiguous Code Alias Name description Groups sqlfluff fix compatible all core その他 AM06 L054 ambiguous.column_referenc es GROUP BYもしくはORDER BY の中で統 一するかどうか 〇 〇 ambiguous ー Name description default values group_by_and_ order_by_style 明示的にカラム名を書くか、暗黙的に数字に するか、とりあえず統一してあればどちらでもい いかを指定 consistent consistent:統一されていればどちらでもいい implicit:1,2,3,4のように明示的に書かないほうで統一 explicit:カラム名を明示的に書くほうで統一

Slide 20

Slide 20 text

Anti-pattern Best Practice ルールの属性 設定値 【AM07】 UNIONするセットのクエリはカラム数が一致しているべし カラム数が合わないと面倒くさいことになるので合わせておきましょう 2023/09/08 20 WITH cte AS ( SELECT a, b FROM foo ) SELECT * FROM cte UNION SELECT c, d, e FROM t WITH cte AS ( SELECT a, b FROM foo ) SELECT a, b FROM cte UNION SELECT c, d FROM t Ambiguous Code Alias Name description Groups sqlfluff fix compatible all core その他 AM07 L068 ambiguous.set_columns カラム数を合わせるかどうか 〇 ー ambiguous ー Name description default values ー

Slide 21

Slide 21 text

Capitalisation (大文字小文字のルール)

Slide 22

Slide 22 text

Anti-pattern Best Practice ルールの属性 設定値 【CP01】 キーワードは大文字か小文字か統一すべし 大文字派も小文字派もいるけど、統一はしよう。キーワードはSELECTとかFROMとかです。 2023/09/08 22 select a FROM foo select a from foo Capitalisation Code Alias Name description Groups sqlfluff fix compatible all core その他 CP01 L010 capitalisation.keywords 大文字か小文字か統一するかどうか 〇 〇 capitalization 〇 Name description default values capitalisation_policy 大文字小文字の統一に関するポリシー consistent consistent:統一してあること upper:大文字で統一していること lower:小文字で統一していること capitalise:頭文字が大文字で統一していること ignore_words カンマ区切りで対象外のワードを指定する None ー ignore_words_regex 正規表現で対象外のワードを指定する None 詳しくは公式のリファレンスを確認

Slide 23

Slide 23 text

Anti-pattern Best Practice ルールの属性 設定値 【CP02】 “”で囲まれていない識別子は大文字か小文字かで統一すべし 識別子はSELECTの中で登場する列名とかFROM句の中で登場するテーブルやビューなどのデータベースオブジェクトの名前などです。 2023/09/08 23 select a, B from foo select a, b from foo Capitalisation Code Alias Name description Groups sqlfluff fix compatible all core その他 CP02 L014 capitalisation.identifiers 大文字か小文字か統一するかどうか 〇 〇 capitalization 〇 Name description default values extended_capitalisation_policy 大文字小文字の統一に関するポリシー consistent consistent:統一してあること upper:大文字で統一していること lower:小文字で統一していること pascal:パスカルケースで統一していること(キャメルケースは…?使わないか…) capitalise:頭文字が大文字で統一していること ignore_words カンマ区切りで対象外のワードを指定する None ー ignore_words_regex 正規表現で対象外のワードを指定する None 詳しくは公式のリファレンスを確認 unquoted_identifiers_policy 違反チェックの対象とする“”で囲まれていない 識別子に関するポリシー all ※[sqlfluff:rules] で定義されている all:すべて aliases:エイリアスのみ column_aliasses:カラムエイリアスのみ

Slide 24

Slide 24 text

Anti-pattern Best Practice ルールの属性 設定値 【CP03】 関数名は大文字か小文字かで統一すべし VSCodeだと関数名はシンタックスハイライトが目立ちにくいので、大文字でもいいかなと思う今日この頃。 2023/09/08 24 SELECT sum(a) AS aa, SUM(b) AS bb FROM foo SELECT sum(a) AS aa, sum(b) AS bb FROM foo Capitalisation Code Alias Name description Groups sqlfluff fix compatible all core その他 CP03 L030 capitalisation.functions 大文字か小文字か統一するかどうか 〇 〇 capitalization 〇 Name description default values extended_capitalisation_policy 大文字小文字の統一に関するポリシー consistent consistent:統一してあること upper:大文字で統一していること lower:小文字で統一していること pascal:パスカルケースで統一していること capitalise:頭文字が大文字で統一していること ignore_words カンマ区切りで対象外のワードを指定する None ー ignore_words_regex 正規表現で対象外のワードを指定する None 詳しくは公式のリファレンスを確認

Slide 25

Slide 25 text

Anti-pattern Best Practice ルールの属性 設定値 【CP04】 Booleanやnullは大文字か小文字かで統一すべし VSCodeではtrue, falseはシンタックスハイライト効かないので、大文字でもいいかなと思う今日この頃。 2023/09/08 25 select a, null, TRUE, false from foo select a, null, true, false from foo Capitalisation Code Alias Name description Groups sqlfluff fix compatible all core その他 CP04 L040 capitalisation.literals 大文字か小文字か統一するかどうか 〇 〇 capitalization 〇 Name description default values CP01と同じ

Slide 26

Slide 26 text

Anti-pattern Best Practice ルールの属性 設定値 【CP05】 データ型は大文字か小文字かで統一すべし dbt使うとあまり書くこともないので、そんなに気にしなくてもいいのかなと思う今日この頃 2023/09/08 26 select a::INT as a_int, b::text as b_text from foo select a::INT as a_int, b::TEXT as b_text from foo Capitalisation Code Alias Name description Groups sqlfluff fix compatible all core その他 CP05 L063 capitalisation.types 大文字か小文字か統一するかどうか 〇 ー capitalization 〇 Name description default values CP03と同じ

Slide 27

Slide 27 text

Convention (世の中の一般的に使われている表現に 寄せたいよねというルール)

Slide 28

Slide 28 text

Anti-pattern Best Practice ルールの属性 設定値 【CV01】 <> ではなく、 != を not equal to として使うべし 一般的に != のほうがよく使われませんか?(Excelは…) 2023/09/08 28 SELECT * FROM X WHERE 1 <> 2 SELECT * FROM X WHERE 1 != 2 Convention Code Alias Name description Groups sqlfluff fix compatible all core その他 CV01 L060 convention.not_equal <>の代わりに!=を使うかどうか 〇 ー convention 〇 Name description default values ー

Slide 29

Slide 29 text

Anti-pattern Best Practice ルールの属性 設定値 【CV02】 IFNULLやNVLではなく、COALESCEを使うべし 欠損値を埋めることはよくやりますが、COALESCEが標準的にサポートされているものなのでそれを使いましょう 2023/09/08 29 SELECT ifnull(foo, 0) AS bar_if_null, nvl(foo, 0) AS bar_nvl FROM baz SELECT COALESCE(foo, 0) AS bar_if_null, COALESCE(foo, 0) AS bar_nvl FROM baz Convention Code Alias Name description Groups sqlfluff fix compatible all core その他 CV02 L061 convention.coalesce IFNULLやNVLの代わりにCOALESCEを 使うかどうか 〇 ー convention 〇 Name description default values ー

Slide 30

Slide 30 text

Anti-pattern Best Practice ルールの属性 設定値 【CV03】 SELECT句の最後の末尾には , を付けるべからず SELECT句の末尾の , はエラーになるデータベースがあるので、やめたほうがいいです。(ちょっとめんどくさい構文ルールだと思っている) 2023/09/08 30 SELECT a, b, FROM foo SELECT a, b FROM foo Convention Code Alias Name description Groups sqlfluff fix compatible all core その他 CV03 L038 convention.select_trailing_c omma 末尾のカンマを許容するかどうか 〇 〇 convention 〇 Name description default values select_clause_trailing_comma 末尾のカンマを禁止にするか必須にするか forbid forbid:禁止する require:必須にする

Slide 31

Slide 31 text

Anti-pattern Best Practice ルールの属性 設定値 【CV04】 COUNT(1)やCOUNT(0)ではなく、COUNT(*)を使うべし ANSIで明確に書かれているのはCOUNT(*)らしいからこれを使おう。(COUNT(1) 派の人には会ったことあるけど、count(0) 派の人には会ったことないな) 2023/09/08 31 select count(1) from table_a select count(*) from table_a Convention Code Alias Name description Groups sqlfluff fix compatible all core その他 CV04 L047 convention.count_rows 行の数を数えるときの構文をそろえるかどうか 〇 〇 convention 〇 Name description default values prefer_count_1 COUNT(1) をほかの2つの表現よりも優先するかどうか False (booleanなので割愛) prefer_count_0 COUNT(0) をほかの2つの表現よりも優先するかどうか False (booleanなので割愛)

Slide 32

Slide 32 text

Anti-pattern Best Practice ルールの属性 設定値 【CV05】 NULLに対する比較は IS もしくは IS NOT を使うべし NULLに対する比較演算子は特殊なので IS, IS NOT を使わないのはコーディングエラーの場合が多いと思います。(意図して使うこともあるかも) 2023/09/08 32 SELECT a FROM foo WHERE a = NULL SELECT a FROM foo WHERE a IS NULL Convention Code Alias Name description Groups sqlfluff fix compatible all core その他 CV05 L049 convention.is_null = もしくは != の代わりに IS もしくは IS NOT を使うかどうか 〇 〇 convention 〇 Name description default values ー

Slide 33

Slide 33 text

Anti-pattern Best Practice ルールの属性 設定値 【CV06】 文の末尾は ; で終了するべし dbtだと ; は要らないので、このルールを利用する際は設定値をデフォルトから変更します 2023/09/08 33 SELECT a FROM foo ; SELECT a FROM foo; Convention Code Alias Name description Groups sqlfluff fix compatible all core その他 CV06 L052 convention.terminator 末尾をどう終わらせるか 〇 ー convention 〇 Name description default values multiline_newline 複数行の文の最後を改行するべきか False (booleanなので割愛) require_final_semic olon 最後の ; が必要かどうか (dbtはクエリをラップする際に問題になるのでfalseのままに するべし) False (booleanなので割愛)

Slide 34

Slide 34 text

Anti-pattern Best Practice ルールの属性 設定値 【CV07】 トップレベルの文は () でくくるべからず (これをやることの意味が分からないので、違反が検知されることはないんだろうなと思います) 2023/09/08 34 (SELECT foo FROM bar) SELECT foo FROM bar Convention Code Alias Name description Groups sqlfluff fix compatible all core その他 CV07 L053 convention.statement_brack ets トップレベルの文を () でくくらないようにするか どうか 〇 ー convention 〇 Name description default values ー

Slide 35

Slide 35 text

Anti-pattern Best Practice ルールの属性 設定値 【CV08】 RIGHT JOINの代わりに、LEFT JOINを使うべし これは宗教チックなところもあるのかなと思いますが、個人的には結構大事だと思います。(coreルールでもいい) 2023/09/08 35 SELECT foo.col1, bar.col2 FROM foo RIGHT JOIN bar ON foo.bar_id = bar.id SELECT foo.col1, bar.col2 FROM bar LEFT JOIN foo ON foo.bar_id = bar.id Convention Code Alias Name description Groups sqlfluff fix compatible all core その他 CV08 L055 convention.left_join LEFT JOINに統一するかどうか 〇 ー convention ー Name description default values ー

Slide 36

Slide 36 text

Anti-pattern Best Practice ルールの属性 設定値 【CV09】 使ってはいけないキーワードがあれば検知できます 特定の関数を使わせないとか独自のルールを適用したいとか(単語のみで大文字小文字の区別はできないのであまり頑張りすぎなくてもいいかなと思います) 2023/09/08 36 SELECT foo::int FROM deprecated_table WHERE 1 = 1 SELECT foo::integer FROM another_table WHERE 1 = 1 Convention Code Alias Name description Groups sqlfluff fix compatible all core その他 CV09 L062 convention.blocked_words 特定の単語を利用できないようにする 〇 ー convention ー Name description default values blocked_regex 禁止の単語の正規表現 None ー blocked_words 禁止の単語のカンマ区切りのリスト None ー match_source テンプレートを適用する前の正規表現にマッチさせるかどうか False (booleanなので割愛) -- sqlfluff:rules:convention.blocked_words:blocked_words:deprecated_table,int インラインで設定することはないと思いますが、以下のように設定した場合の例です。

Slide 37

Slide 37 text

Anti-pattern Best Practice ルールの属性 設定値 【CV10】 リテラルに利用するクオートは統一すべし 一部のデータベースはシングルクオートとダブルクオートの両方を利用できるので、エスケープを使用しないようにする用途以外は統一する 2023/09/08 37 select "abc", 'abc', "¥"", "abc" = 'abc' from foo select "abc", "abc", '"', "abc" = "abc" from foo Convention Code Alias Name description Groups sqlfluff fix compatible all core その他 CV10 L064 convention.quoted_literals クオートの種類を統一するかどうか 〇 ー convention 〇 “” がサポートされるデータベースのみ有効 Name description default values force_enable デフォルトで無効なdialectこのルールが動くのかどうか False (booleanなので割愛) preferred_quoted_li teral_style 優先するクオートの種類を指定 consistent consistent:最初に登場するものを優先する single_quotes:’’ を優先する double_quotes:”” を優先する

Slide 38

Slide 38 text

Anti-pattern Best Practice ルールの属性 設定値 【CV11】 キャストの書き方は統一すべし 個人的には <対象のカラム>::<データ型> が直感的で好きですが、移植性を考えると標準のCAST()関数がよさげです。 2023/09/08 38 SELECT CONVERT(int, 1) AS bar, 100::int::text, CAST(10 AS text) AS coo FROM foo SELECT CAST(1 AS int) AS bar, CAST(CAST(100 AS int) AS text), CAST(10 AS text) AS coo FROM foo Convention Code Alias Name description Groups sqlfluff fix compatible all core その他 CV11 L067 convention.casting_style キャストの書き方をそろえるかどうか 〇 ー convention 〇 Name description default values preferred_type_casting_style キャストのスタイルの指定 consistent consistent:最初に登場した書き方にそろえる shorthand::: を利用した書き方にそろえる convert:CONBERT関数を利用した書き方にそろえる cast:CAST関数を利用した書き方にそろえる

Slide 39

Slide 39 text

Jinja (Jinjaのルール)

Slide 40

Slide 40 text

Anti-pattern Best Practice ルールの属性 設定値 【JJ01】 Jinjaのタグでは1つの半角スペースを両側に付けるべし なんとなくつけたくなる半角スペースを強制させることができます。見やすさは大事です! 2023/09/08 40 SELECT {{ a }} FROM {{ref('foo')}} SELECT {{ a }} FROM {{ ref('foo') }} Jinja Code Alias Name description Groups sqlfluff fix compatible all core その他 JJ01 L046 jinja.padding 両側に半角スペースをつけるかどうか 〇 〇 jinja 〇 Name description default values ー

Slide 41

Slide 41 text

Layout (文字配置のルール)

Slide 42

Slide 42 text

Anti-pattern Best Practice ルールの属性 設定値 【LT01】 スペースを適切に入れるべし ここはルールのカスタマイズをしようとするとややこしいので、設定に関してはこのセクションの末尾に記載します 2023/09/08 42 SELECT a, b(c) AS d•• FROM foo•••• INNER JOIN bar USING(a) SELECT a, b(c) AS d FROM foo INNER JOIN bar USING (a) Layout Code Alias Name description Groups sqlfluff fix compatible all core その他 LT01 L001 ※ layout.spacing スペースの入れ方をルールにしたがったものに するかどうか 〇 〇 layout 〇 Name description default values ※L005, L006, L008, L023, L024, L039, L048, L071 [sqlfluff:layout] の設定値はまとめて本セクションの末尾で詳細を記載する (•は半角スペースを示す)

Slide 43

Slide 43 text

Anti-pattern Best Practice ルールの属性 設定値 【LT02】 インデントを適切に入れるべし スペースもしくはタブにそろえて、スペースの場合はちゃんと指定した倍数になっているようにする 2023/09/08 43 SELECT a, b FROM foo SELECT a, b FROM foo Layout Code Alias Name description Groups sqlfluff fix compatible all core その他 LT02 L002 ※ layout.indent インデントの入れ方をルールにしたがったもの にするかどうか 〇 〇 layout 〇 Name description default values ※L003, L004 (•は半角スペースを示す) [sqlfluff:layout] の設定値はまとめて本セクションの末尾で詳細を記載する

Slide 44

Slide 44 text

Anti-pattern Best Practice ルールの属性 設定値 【LT03】 演算子の前後で改行する場合は標準ルールにそろえるべし どうしても識別子が長くなりがちなので、見通ししやすくするために改行することもあると思います。ルールを決めましょう! 2023/09/08 44 SELECT a + b FROM foo SELECT a + b FROM foo Layout Code Alias Name description Groups sqlfluff fix compatible all core その他 LT03 L007 layout.operators 演算子の改行前後の位置のルールにした がったものにするかどうか 〇 ー layout 〇 Name description default values [sqlfluff:layout] の設定値はまとめて本セクションの末尾で詳細を記載する

Slide 45

Slide 45 text

Anti-pattern Best Practice ルールの属性 設定値 【LT04】 , は文頭か文末かどっちかに統一すべし 宗教上の理由でこちらは大戦争が起きるかもしれないですが、ルールを決めて統一しましょう … ! 2023/09/08 45 SELECT a , b, c FROM foo SELECT a, b, c FROM foo Layout Code Alias Name description Groups sqlfluff fix compatible all core その他 LT04 L019 layout.commas カンマの位置をルールにしたがったものにする かどうか 〇 ー layout 〇 Name description default values [sqlfluff:layout] の設定値はまとめて本セクションの末尾で詳細を記載する

Slide 46

Slide 46 text

Anti-pattern Best Practice ルールの属性 設定値 【LT05】 1行は長すぎないようにすべし これはレイアウトの設定とは別にコメントアウトに関してのチェックの設定値があるので記載しておきます。 2023/09/08 46 (割愛) (割愛) Layout Code Alias Name description Groups sqlfluff fix compatible all core その他 LT05 L016 layout.long_lines 1行の長さをルールにしたがったものにするかど うか 〇 〇 layout 〇 Name description default values ignore_comment_clauses 行末のコメントアウト部分を含めるかどうか False (booleanなので割愛) ignore_comment_lines コメントアウト行を検査対象に含めるかどうか False (booleanなので割愛)

Slide 47

Slide 47 text

Anti-pattern Best Practice ルールの属性 設定値 【LT06】 関数名の直後に () を付けるべし 関数名と()の間のスペースは見ずらいと思います!(異論は認めますので、異論がある方は設定を変更してください) 2023/09/08 47 SELECT sum (a) FROM foo SELECT sum(a) FROM foo Layout Code Alias Name description Groups sqlfluff fix compatible all core その他 LT06 L017 layout.functions 関数名と()の間にスペースを含めるかどうか 〇 〇 layout 〇 Name description default values [sqlfluff:layout] の設定値はまとめて本セクションの末尾で詳細を記載する

Slide 48

Slide 48 text

Anti-pattern Best Practice ルールの属性 設定値 【LT07】 WITH句を閉じるときは改行すべし これは異論がある人はあまりいないのでは? 2023/09/08 48 WITH zoo AS ( SELECT a FROM foo) SELECT * FROM zoo WITH zoo AS ( SELECT a FROM foo ) SELECT * FROM zoo Layout Code Alias Name description Groups sqlfluff fix compatible all core その他 LT07 L018 layout.cte_bracket CTEを閉じる際に改行をするかどうか 〇 〇 layout 〇 Name description default values [sqlfluff:layout] の設定値はまとめて本セクションの末尾で詳細を記載する

Slide 49

Slide 49 text

Anti-pattern Best Practice ルールの属性 設定値 【LT08】 WITH句を閉じた後は改行を追加すべし これも異論がある人はあまりいないのでは? 2023/09/08 49 WITH plop AS ( SELECT * FROM foo ) SELECT a FROM plop WITH plop AS ( SELECT * FROM foo ) SELECT a FROM plop Layout Code Alias Name description Groups sqlfluff fix compatible all core その他 LT08 L022 layout.cte_newline CTEを閉じた後に改行をするかどうか 〇 〇 layout 〇 Name description default values [sqlfluff:layout] の設定値はまとめて本セクションの末尾で詳細を記載する

Slide 50

Slide 50 text

Anti-pattern Best Practice ルールの属性 設定値 【LT09】 SELECTの対象が1つしかない場合を除いて改行すべし 1つの場合は改行しなくてもいいのかどうか賛否両論かと思いますので、鬱陶しい場合は –noqa: LT09 をSELECTの行に入れればOKです! 2023/09/08 50 WITH sample_tbl AS ( SELECT a, b FROM foo ) SELECT a FROM sample_tbl WITH sample_tbl AS ( SELECT a, b FROM foo ) SELECT a FROM sample_tbl Layout Code Alias Name description Groups sqlfluff fix compatible all core その他 LT09 L036 layout.select_targets SELECTの対象が1つしかない場合を除いて 改行を強制するかどうか 〇 ー layout 〇 Name description default values wildcard_policy ワイルドカード * の扱いの設定 single single:単一の対象として扱う(改行をしなくていい) multiple:複数の対象として扱う(改行を必要とする)

Slide 51

Slide 51 text

Anti-pattern Best Practice ルールの属性 設定値 【LT10】 DISTINCTなどは修飾子はSELECTと同じ行に書くべし この辺りは好みですね。 2023/09/08 51 select distinct a, b from x select distinct a, b from x Layout Code Alias Name description Groups sqlfluff fix compatible all core その他 LT10 L041 layout.select_modifiers 修飾子をSELECTと同じ行に書くかどうか 〇 〇 layout 〇 Name description default values [sqlfluff:layout] の設定値はまとめて本セクションの末尾で詳細を記載する

Slide 52

Slide 52 text

Anti-pattern Best Practice ルールの属性 設定値 【LT11】 Set Operator (UNION系) は前後で改行すべし これは異論ないでしょう! 2023/09/08 52 SELECT 'a' AS col UNION ALL SELECT 'b' AS col SELECT 'a' AS col UNION ALL SELECT 'b' AS col Layout Code Alias Name description Groups sqlfluff fix compatible all core その他 LT11 L065 layout.set_operators Set Operatorの前後で改行を強制するか どうか 〇 〇 layout 〇 Name description default values [sqlfluff:layout] の設定値はまとめて本セクションの末尾で詳細を記載する

Slide 53

Slide 53 text

Anti-pattern Best Practice ルールの属性 設定値 【LT12】 ファイルの末尾は改行1行だけにすべし これが嫌な人はいないのでは? 2023/09/08 53 SELECT a FROM foo$ SELECT a FROM foo $ Layout Code Alias Name description Groups sqlfluff fix compatible all core その他 LT12 L009 ※ layout.end_of_file ファイルの末尾を改行のみの1行にすべし 〇 〇 layout 〇 Name description default values ※layout.end-of-file [sqlfluff:layout] の設定値はまとめて本セクションの末尾で詳細を記載する ($はファイルの末尾を示す)

Slide 54

Slide 54 text

Anti-pattern Best Practice ルールの属性 設定値 【LT13】 ファイルは改行もしくは空白で始まるべからず (私はコメントとか入れたりしたいのと、dbtだとconfigブロックを書いたりする影響で悪さをするので、このルールは除外にしています) 2023/09/08 54 ^ -- noqa: disable=LT09 SELECT a FROM foo -- noqa: disable=LT09 SELECT a FROM foo Layout Code Alias Name description Groups sqlfluff fix compatible all core その他 LT13 L050 layout.start_of_file ファイルの改行もしくは空白で始まらないよう にするかどうか 〇 ー layout 〇 Name description default values [sqlfluff:layout] の設定値はまとめて本セクションの末尾で詳細を記載する (^はファイルの先頭を示す)

Slide 55

Slide 55 text

【Layout】 レイアウト全般の設定に関して 2023/09/08 55 Name description default values max_line_length 1行の最大文字数 80 数字を指定 [sqlfluff] 詳しくはこのファイルを読んでみるといいです(ドキュメントに記載のない情報はここから読み取ったものをまとめています) https://github.com/sqlfluff/sqlfluff/blob/main/src/sqlfluff/core/rules/config_info.py

Slide 56

Slide 56 text

【Layout】 レイアウト全般の設定に関して 2023/09/08 56 Name description default values indent_unit インデントとして追加するもの space space:半角スペース tab:タブ tab_space_size タブとして認識される半角スペースのサイズ 4 100までの整数 indented_joins JOIN句でインデントを追加するかどうか False (booleanなので割愛) indented_ctes CTEの中でインデントを追加するかどうか False (booleanなので割愛) indented_using_on JOINのON句でインデントを追加するかどうか True (booleanなので割愛) indented_on_contents ONの中の条件式が複数ある場合にインデントを追加するかどうか True (booleanなので割愛) indented_then CASEのTHENの後のインデントを追加するかどうか True (booleanなので割愛) indented_then_contents THENの値の中でインデントを追加するかどうか(たぶん…) True (booleanなので割愛) allow_implicit_indents 暗黙的なインデントを許可するかどうか False (booleanなので割愛) template_blocks_indent jinjaのようなテンプレートのインデントをするかどうか True (booleanなので割愛) skip_indentation_in インデントの編集の対象外とする文字列の , 区切りのリスト script_content (よくわからない…) trailing_comments 長い文末のコメントアウトがある場合にその行の前後どちらに移動 させるか before before:前 after:後ろ [sqlfluff: identation] (ドキュメントに記載のない情報はここから読み取ったものをまとめています) https://github.com/sqlfluff/sqlfluff/blob/main/src/sqlfluff/core/rules/config_info.py

Slide 57

Slide 57 text

【Layout】 レイアウト全般の設定に関して 2023/09/08 57 カテゴリ / Name description default values comma spacing_before , の前の単語とのスペースに関して touch single:改行がない場合、スペース1つ分空ける single:inline:改行を許さず、スペースを1つ分空ける touch:改行がない場合、スペースを空けない touch:inline:改行を許さず、スペースを空けない any:なんでもOK line_position 1行における位置取り trailing trailing:行の末尾 leading:行の先頭 alone:前後で改行して、その行で一つだけにする alone:strict:その行だけを強制する(一部のルールのみ 適用を考える) binary_operator ※二項演算子(+, -など) spacing_within 二項演算子の前後のスペースに関して touch (spacing系は同じ) line_posittion 1行における位置取り leading (line_positionは同じ) statement_terminator spacing_before 文末の文字(;)の前の単語とのスペース に関して touch (spacing系は同じ) line_position 1行における位置取り trailing (line_positionは同じ) [sqlfluff:layout.type.<カテゴリ>] (ドキュメントに記載のない情報はここから読み取ったものをまとめています) https://github.com/sqlfluff/sqlfluff/blob/main/src/sqlfluff/core/rules/config_info.py

Slide 58

Slide 58 text

【Layout】 レイアウト全般の設定に関して 2023/09/08 58 カテゴリ / Name description default values end_of_file spacing_before EOFの前の単語とのスペースに関して touch (spacing系は同じ) set_operator line_posittion 1行における位置取り alone:strict (line_positionは同じ) start_bracket spacing_after ( の後の単語とのスペースに関して touch (spacing系は同じ) end_bracket spacing_before ) の前の単語とのスペースに関して touch (spacing系は同じ) start_square_bracket spacing_after ( の後ろの単語とのスペースに関して touch (spacing系は同じ) end_square_bracket spacing_before ) の前の単語とのスペースに関して touch (spacing系は同じ) start_angle_bracket spacing_after < の後の単語とのスペースに関して touch (spacing系は同じ) end_angle_bracket spacing_before > の前の単語とのスペースに関して touch (spacing系は同じ) [sqlfluff:layout.type.<カテゴリ>]

Slide 59

Slide 59 text

【Layout】 レイアウト全般の設定に関して 2023/09/08 59 カテゴリ / Name description default values casting_operator ※キャストで利用する :: のこと spacing_before :: の前の単語とのスペースに関して touch (spacing系は同じ) spacing_after :: の後の単語とのスペースに関して? touch:inline (spacing系は同じ) slice ※arrayなどをいじるときに利用する[:] spacing_before : の前の単語とのスペースに関して touch (spacing系は同じ) spacing_after : の後の単語とのスペースに関して touch (spacing系は同じ) comparison_operator ※比較演算子 > < =など spacing_within ※なんかsingleで動いていそう… touch (spacing系は同じ) line_position 比較演算子の前後で改行したときの位置 leading (line_positionは同じ) assignment_operator ※代入演算子 := とか = spacing_within ※なんかsingleで動いていそう…? touch (spacing系は同じ) line_position 代入演算子の前後で改行したときの位置 leading (line_positionは同じ) [sqlfluff:layout.type.<カテゴリ>]

Slide 60

Slide 60 text

【Layout】 レイアウト全般の設定に関して 2023/09/08 60 カテゴリ / Name description default values object_referenc spacing_within ※おそらくオブジェクトの名前かな?ただよくわからない… touch:inline (spacing系は同じ) numeric_literal spacing_within ※数字か?ただよくわからない… touch:inline (spacing系は同じ) sign_indicato spacing_after ※おそらく標識変数とか?ただよくわからない… touch:inline (spacing系は同じ) tilde spacing_after ※~ ビット演算とか?ただよくわからない… touch:inline (spacing系は同じ) function_name spacing_within ※関数名?ただよくわからない… touch:inline (spacing系は同じ) spacing_after touch:inline (spacing系は同じ) array_type spacing_within ※arrayの型ただよくわからない… touch:inline (spacing系は同じ) [sqlfluff:layout.type.<カテゴリ>] この辺りはよくわからないので、いじらなくていいと思います。

Slide 61

Slide 61 text

【Layout】 レイアウト全般の設定に関して 2023/09/08 61 カテゴリ / Name description default values typed_array_literal spacing_within わからない touch (spacing系は同じ) sized_array_type spacing_within わからない touch (spacing系は同じ) struct_type spacing_within わからない touch:inline (spacing系は同じ) bracketed_arguments spacing_before わからない touch:inline (spacing系は同じ) typed_struct_literal spacing_within わからない touch (spacing系は同じ) semi_structured_expression spacing_within 半構造化とかってことはjsonとか?よくわからない touch:inline (spacing系は同じ) spacing_before touch:inline (spacing系は同じ) [sqlfluff:layout.type.<カテゴリ>] この辺りはよくわからないので、いじらなくていいと思います。

Slide 62

Slide 62 text

【Layout】 レイアウト全般の設定に関して 2023/09/08 62 カテゴリ / Name description default values array_accessor spacing_before よくわからない touch:inline (spacing系は同じ) colon spacing_before : だと思うけどよくわからない touch (spacing系は同じ) comment spacing_before コメントの前のスペースに関して any (spacing系は同じ) spacing_after これってどういうケースなのかよくわからない any (spacing系は同じ) placeholder spacing_before プレースホルダだと思いますがよくわからない any (spacing系は同じ) spacing_after any (spacing系は同じ) common_table_expression spacing_within CTEだと思いますがよくわからない single:inline (spacing系は同じ) template_loop spacing_before ちょっとよくわからない any (spacing系は同じ) spacing_after any (spacing系は同じ) [sqlfluff:layout.type.<カテゴリ>] この辺りはよくわからないので、いじらなくていいと思います。

Slide 63

Slide 63 text

【Layout】 レイアウト全般の設定に関して 2023/09/08 63 カテゴリ / Name description default values select_clause line_position SELECT句の位置 ※1行に収めることもよくあるのであんまり厳しくないalone alone (line_positionは同じ) ※alone:strictを指定しないといけない where_clause line_position WHERE句の位置 alone 同上 from_clause line_position FROM句の位置 alone 同上 join_clause line_position JOIN句の位置 alone 同上 groupby_clause line_position GROUP BY句の位置 alone 同上 orderby_clause line_position ORDER BY句の位置 alone 同上 having_clause line_position HAVING句の位置 alone 同上 limit_clause line_position LIMIT句の位置 alone 同上 [sqlfluff:layout.type.<カテゴリ>]

Slide 64

Slide 64 text

References (特殊な文字や予約語とか使わずに安全 にテーブルを参照するルール) カラム名だけ書かずに、 <テーブル名>.<カラム名> のように書くことをReferencesと言っていると理解

Slide 65

Slide 65 text

Anti-pattern Best Practice ルールの属性 設定値 【RF01】 FROM句に登場しないオブジェクトは参照するべからず 当たり前かと思いきや特殊なケースでは誤検知を起こしたりするので結構難しい問題な場面があるので、dialectによっては無効にしている 2023/09/08 65 SELECT vee.a FROM foo SELECT a FROM foo References Code Alias Name description Groups sqlfluff fix compatible all core その他 RF01 L025 references.from FROM句に登場しないオブジェクトを参照し ないようにするかどうか 〇 〇 references ー Name description default values force_enable デフォルトでこのルールが無効になっている dialectにおいて、ルールを適用させるかどうか False (booleanなので割愛)

Slide 66

Slide 66 text

Anti-pattern Best Practice ルールの属性 設定値 【RF02】 複数のテーブルやビューからSELECTする場合は修飾すべし これは怠らないほうがいいです。これを強制できると品質が安定すると思うので、coreのルールじゃないのですが、個人的に推奨です。 2023/09/08 66 SELECT a, b FROM foo LEFT JOIN vee ON foo.a = vee.a SELECT foo.a, vee.b FROM foo LEFT JOIN vee ON foo.a = vee.a References Code Alias Name description Groups sqlfluff fix compatible all core その他 RF02 L027 references.consistent 参照を必要とするかどうか 〇 ー references ー Name description default values ー

Slide 67

Slide 67 text

Anti-pattern Best Practice ルールの属性 設定値 【RF03】 一つのテーブルに対する参照をつけるかどうかは統一すべし 一回Referenceをしたなら全部しましょう。私はしなくて一つのテーブルの場合は参照しなくていい派なので、single_table_referencesはunqualifiedでもいいと思います。 2023/09/08 67 SELECT a, foo.b FROM foo SELECT a, b FROM foo References Code Alias Name description Groups sqlfluff fix compatible all core その他 RF03 L028 references.consistent 1つのテーブルの場合にReferenceをするか どうか 〇 ー references 〇 Name description default values force_enable デフォルトでこのルールが無効になっている dialectにおいて、ルールを適用させるかどうか False (booleanなので割愛) single_table_refer ences 一つのテーブルのSELECT文でReferenceを 統一する方針 consistent consistent:最初に登場するものを優先する qualified:参照する方で統一する unqualified:参照しない方で統一する

Slide 68

Slide 68 text

Anti-pattern Best Practice ルールの属性 設定値 【RF04】 キーワード(予約語)を識別子(テーブル名やエイリアスなど) で使うべからず “”でくくれば使えるのですが、SQLが民主化していくとすべての人が予約語を全部覚えているわけはないので、より混乱していくかと思います。 2023/09/08 68 SELECT sum.a FROM foo AS sum SELECT vee.a FROM foo AS vee References Code Alias Name description Groups sqlfluff fix compatible all core その他 RF04 L029 references.keywords 予約語を識別子で使えるようにするかどうか 〇 ー references ー Name description default values ignore_words 無視するキーワードのカンマ区切りのリスト None ー ignore_words_regex 無視するキーワードの正規表現 None 詳しくは公式のリファレンスを確認 quoted_identifiers_policy 違反のフラグを立てる””で囲まれた識別子の種類 none all:すべてが対象 aliases:テーブルエイリアスおよびカラムエイリアスのみが対象 column_aliases:カラムエイリアスのみが対象 None:すべて対象外 unquoted_identifiers_policy 違反のフラグを立てる””で囲まれていない識別子の種類 aliases all:すべてが対象 aliases:テーブルエイリアスおよびカラムエイリアスのみが対象 column_aliases:カラムエイリアスのみが対象 Linterが効かない…?

Slide 69

Slide 69 text

Anti-pattern Best Practice ルールの属性 設定値 【RF05】 識別子に特殊文字を使うべからず そりゃそうだというルールですね。アンダーバーとか使いましょう! 2023/09/08 69 SELECT "Internal Space", "Greater>Than", "Less

Slide 70

Slide 70 text

Anti-pattern Best Practice ルールの属性 設定値 【RF06】 不要なクオートは避けるべし 不要な””はコーディング時の書き味が悪くなるのでやめた方がいいですよね。 2023/09/08 70 SELECT 123 AS "foo" SELECT 123 AS foo References Code Alias Name description Groups sqlfluff fix compatible all core その他 RF06 L059 references.quoting 不要なクオートを避けるかどうか 〇 ー references 〇 Name description default values force_enable デフォルトで無効なdialectでルールを利用できるようにするかどうか False (booleanなので割愛) ignore_words 無視するキーワードのカンマ区切りのリスト None ー ignore_words_regex 無視するキーワードの正規表現 None 詳しくは公式のリファレンスを確認 prefer_quoted_identifiers 全ての識別子がクオートされる必要があるかどうか (これをTrueにするとクオートのルールが逆になる) False (booleanなので割愛) prefer_quoted_keywords 識別子として予約語がクオートされる必要があるかどうか False (booleanなので割愛)

Slide 71

Slide 71 text

Structure (クエリの構造を見やすく・わかりやすくする ためのルール)

Slide 72

Slide 72 text

Anti-pattern Best Practice ルールの属性 設定値 【ST01】 else null は冗長なので書くべからず 書いたことなかったけど、いわれると確かにそうなのかと納得するやつ 2023/09/08 72 select case when name like '%cat%' then 'meow' when name like '%dog%' then 'woof' else null end from x select case when name like '%cat%' then 'meow' when name like '%dog%' then 'woof' end from x Structure Code Alias Name description Groups sqlfluff fix compatible all core その他 ST01 L035 structure.else_null else null を省略するかどうか 〇 ー structure 〇 Name description default values ー

Slide 73

Slide 73 text

Anti-pattern Best Practice ルールの属性 設定値 【ST02】 不必要なCASE文は使うべからず NULLの分岐はCOALESCEとか使いましょう(方言ですが、NVL2も便利です。NVLはCOALESCEに統一しましょう) 2023/09/08 73 SELECT CASE WHEN fab > 0 THEN true ELSE false END AS is_fab FROM fancy_table SELECT COALESCE (fab > 0, FALSE) AS is_fab FROM fancy_table Structure Code Alias Name description Groups sqlfluff fix compatible all core その他 ST02 L043 structure.simple_case 簡単なCASE文を関数で代用するか 〇 ー structure 〇 Name description default values ー

Slide 74

Slide 74 text

Anti-pattern Best Practice ルールの属性 設定値 【ST03】 使っていないCTE(共通テーブル式)は消すべし というか使っていないというよりテーブル名とか間違っていませんか?(私は大体そんな感じでこのルールに助けられています) 2023/09/08 74 WITH cte1 AS ( SELECT a FROM t ), cte2 AS ( SELECT b FROM u ) SELECT * FROM cte1 WITH cte1 AS ( SELECT a FROM t ) SELECT * FROM cte1 Structure Code Alias Name description Groups sqlfluff fix compatible all core その他 ST03 L045 structure.unused_cte 使っていないCTEをそのままにするかどうか 〇 〇 structure ー Name description default values ー

Slide 75

Slide 75 text

Anti-pattern Best Practice ルールの属性 設定値 【ST04】 ELSE句の中でネストされたCASEはフラット化すべし ついついやってしまう気持ちはわかりますが、そのSQLは可読性が低いでしょう…! 2023/09/08 75 SELECT CASE WHEN species = 'Cat' THEN 'Meow' ELSE CASE WHEN species = 'Dog' THEN 'Woof' END END AS sound FROM mytable SELECT CASE WHEN species = 'Cat' THEN 'Meow' WHEN species = 'Dog' THEN 'Woof' END AS sound FROM mytable Structure Code Alias Name description Groups sqlfluff fix compatible all core その他 ST04 L058 structure.nested_case ELSE内でネストされたCASEをフラット化す るかどうか 〇 ー structure 〇 Name description default values ー

Slide 76

Slide 76 text

Anti-pattern Best Practice ルールの属性 設定値 【ST05】 JOIN/FROM句の中でサブクエリを書く代わりにCTEにすべし デフォルトだとJOIN句の中では許されず、FROM句の中では許される。(dialectによっては、CTEを利用できない場合がある。その際はルール自体の無効化を推奨) 2023/09/08 76 select a.x, a.y, b.z from a inner join ( select x, z from b ) using (x) with prep_1 as ( select x, z from b ) select a.x, a.y, b.z from a inner join prep_1 using (x) Structure Code Alias Name description Groups sqlfluff fix compatible all core その他 ST05 L042 structure.subquery サブクエリの代わりにCTEにするかどうか 〇 ー structure 〇 Name description default values forbid_subquery_in どの句の中のサブクエリをLintの対象にするか join join:JOIN句の中で許されない(Lintの対象) from:FROM句の中で許されない(Lintの対象) both:JOINとFROMの中で許されない(Lintの対象)

Slide 77

Slide 77 text

Anti-pattern Best Practice ルールの属性 設定値 【ST06】 * → 単純なカラムの抽出 → 計算・集計 の順に書くべし * を使うのは良くないよとAM04でも言っていましたが、使うとして位置は頭がいいらしいです。そして複雑な計算は末尾がいいらしいです。 2023/09/08 77 select a, *, row_number() over (partition by id order by date) as y, b from x select *, a, b, row_number() over (partition by id order by date) as y from x Structure Code Alias Name description Groups sqlfluff fix compatible all core その他 ST06 L034 structure.column_order カラムの順番にルールを持たせるかどうか 〇 ー structure 〇 Name description default values ー

Slide 78

Slide 78 text

Anti-pattern Best Practice ルールの属性 設定値 【ST07】 USING を利用せずに、キーを指定すべし これは無効化していいかなと思っています。好きな人はONのままにしておけばいいと思います。 2023/09/08 78 SELECT table_a.field_1, table_b.field_2 FROM table_a INNER JOIN table_b USING (id) SELECT table_a.field_1, table_b.field_2 FROM table_a INNER JOIN table_b ON table_a.id = table_b.id Structure Code Alias Name description Groups sqlfluff fix compatible all core その他 ST07 L032 structure.using usingを使わないようにするかどうか 〇 ー structure 〇 Name description default values ー

Slide 79

Slide 79 text

Anti-pattern Best Practice ルールの属性 設定値 【ST08】 DISTINCT は () を使うべからず DISTINCTの () は意味がなく、誤解を生むだけの百害あって一利なしなので、つけないでください(関数ではないし、特定のカラムに限定できないし…) 2023/09/08 79 SELECT DISTINCT(a), b FROM foo SELECT DISTINCT a, b FROM foo -- もしくは以下 SELECT DISTINCT a, b FROM foo Structure Code Alias Name description Groups sqlfluff fix compatible all core その他 ST08 L015 structure.distinct DISTINCT の () を使わないようにするかど うか 〇 〇 structure 〇 Name description default values ー

Slide 80

Slide 80 text

Anti-pattern Best Practice ルールの属性 設定値 【ST09】 JOINで並べたテーブルの参照の順番は統一すべし 説明難しいのでサンプル見ておいてください。earlierに設定している例です。 2023/09/08 80 select foo.a, foo.b, bar.c from foo left join bar -- This subcondition does not list -- the table referenced earlier first: on bar.a = foo.a -- Neither does this subcondition: and bar.b = foo.b select foo.a, foo.b, bar.c from foo left join bar on foo.a = bar.a and foo.b = bar.b Structure Code Alias Name description Groups sqlfluff fix compatible all core その他 ST09 ー structure.join_condition_ord er 〇 ー structure 〇 Name description default values preferred_first_ta ble_in_join_clause テーブルの参照の順番をどっちが先になるように するか earlier earlier:左が先になるようにする later:右が先になるようにする

Slide 81

Slide 81 text

TSQL (T-SQLのべからず集)

Slide 82

Slide 82 text

Anti-pattern Best Practice ルールの属性 設定値 【TQ01】 ユーザ定義のプロシージャの名前は SP_ の接頭辞を使うべからず SP_で始まるのはシステムが利用するプロシージャである可能性があるので名前の衝突のリスクがあるので、使わないほうがいい 2023/09/08 82 CREATE PROCEDURE dbo.sp_pull_data AS SELECT ID, DataDate, CaseOutput FROM table1 CREATE PROCEDURE dbo.pull_data AS SELECT ID, DataDate, CaseOutput FROM table1 TSQL Code Alias Name description Groups sqlfluff fix compatible all core その他 TQ01 L056 tsql.sp_prefix sp_という接頭辞をプロシージャの名前に付 けるかどうか 〇 ー structure ? Name description default values ー