SQLFluffのルール一覧


Rule Reference

https://docs.sqlfluff.com/en/stable/rules.html

Rules

Rule_L001 末尾の空白は必要なし!

sqlfluff fixでも修正できる。

SELECT
     a
 FROM foo••

↓↓↓↓

SELECT
    a
FROM foo

Rule_L002 空白文字にタブと空白は混在しない!

NG

SELECT
 ••→a
 FROM foo

Rule_L003 インデント数は揃える!

NG

SELECT
 ••••a,
 •••••b
 FROM foo

Rule_L004 インデントに使う文字が統一してない!

NG

select
 ••••a,
 →   b
 from foo

Rule_L005 カンマ前の空白はいらない!

NG

SELECT
     a•,
     b
 FROM foo

Rule_L006 演算子(+とか)は、前後に空白!

NG

SELECT
   a +b
FROM foo

Rule_L007 演算子(+とか)は改行の前後どちらか

operator_new_lines = afterの場合、
NG at after, OK at before

SELECT
    a +
    b
FROM foo

OK at after, NG at before

SELECT
    a
    + b
FROM foo

Rule_L008 カンマの後には、空白!(コメント時以外)

NG

SELECT
    *
FROM foo
WHERE a IN ('plop','zoo')

OK

SELECT
     *
 FROM foo
 WHERE a IN ('plop',•'zoo')

Rule_L009 ファイルの末尾に改行(のみの行)必要

SELECT
     a
 FROM foo
 ;
 $

Rule_L010 予約語や関数は、小文字or大文字に統一

capitalisation_policy: ['consistent(首尾一貫した?)', 'upper(大文字)', 'lower(小文字)', 'capitalise(頭文字大文字)'].
ignore_words: 無視するキーワードも設定できる

NG

select
    a
FROM foo

Rule_L011 テーブルの別名にAS必要?

NG at implicit, OK at explicit

SELECT
    voo.a
FROM foo voo

OK at implicit, NG at explicit

SELECT
    voo.a
FROM foo AS voo

Rule_L012 カラムの別名にAS必要?

NG at implicit

SELECT
    a alias_col
FROM foo

OK at implicit

SELECT
    a AS alias_col
FROM foo

Rule_L013 計算式カラムにAS必要?

sqlfluff fixでは修正できない
NG

SELECT
    sum(a),
    sum(b)
FROM foo

OK

SELECT
    sum(a) AS a_sum,
    sum(b) AS b_sum
FROM foo

Rule_L014 カラム名は、大文字か小文字に統一する

Rule_L010のcapitalisation_policyに関連する
Config

  • extended_capitalisation_policy: consistent, uppser, lower, pascal, capitalize
  • ignore_words: カンマ区切りで無視するワードを列挙
  • unquoted_identifiers_policy all, aliasies, column_aliases
    NG aとBで大文字/小文字が統一されていない
select
    a,
    B
from foo

OK

select
    a,
    b
from foo

-- Also good

select
    A,
    B
from foo

Rule_L015 DISTINCTは丸括弧を使わない!

NG

SELECT DISTINCT(a), b FROM foo

OK

SELECT DISTINCT a, b FROM foo

Rule_L016 列長すぎ!

Rule_L017 関数のカッコのあとに空白はいらない!!

NG

SELECT
    sum (a)
FROM foo

OK

SELECT
    sum(a)
FROM foo

Rule_L018 WITHの閉じカッコのインデントを揃える!

NG

WITH zoo AS (
     SELECT a FROM foo
 ••••)

 SELECT * FROM zoo

OK

WITH zoo AS (
    SELECT a FROM foo
)

SELECT * FROM zoo

Rule_L019 カンマの位置は行頭or行末!

config:

  • leading : 行頭
    -  tailing : 行末

NG

SELECT
    a
    , b,
    c
FROM foo

OK ( tailing )

SELECT
    a,
    b,
    c
FROM foo

OK ( leading )

SELECT
    a
    , b
    , c
FROM foo

Rule_L020 テーブルの別名に重複はNG

NG

SELECT
    t.a,
    t.b
FROM foo AS t, bar AS t

OK

SELECT
    f.a,
    b.b
FROM foo AS f, bar AS b

Rule_L021 DISTINCT と GROUP BYは同時に使うのNG!

NG

SELECT DISTINCT
    a
FROM foo
GROUP BY a

OK

SELECT DISTINCT
    a
FROM foo

DISTINCTGROUP BYなら、DISTINCTを使うのがGood

Rule_L022 WITH句のあとは一行空行を入れるべし

config: comma_style (WITH句のカンマの位置)

  • leading ※こちらのほうが好き・・・個人的に
  • trailing
    NG
WITH plop AS (
    SELECT * FROM foo
)
SELECT a FROM plop

OK : 空行追加

WITH plop AS (
    SELECT * FROM foo
)

SELECT a FROM plop

Rule_L023 WITH句のASの後に空白1つ必要

NG

WITH plop AS(
    SELECT * FROM foo
)

SELECT a FROM plop

OK

WITH plop AS•(
     SELECT * FROM foo
 )

 SELECT a FROM plop

Rule_024 JOIN句で使うUSINGの後に空白一つ必要

NG

SELECT b
FROM foo
LEFT JOIN zoo USING(a)

OK

SELECT b
 FROM foo
 LEFT JOIN zoo USING (a)

Rule_L025 テーブルエイリアスを使うならSQL中でも使うべし

NG ( zoo を使ってない)

SELECT
    a
FROM foo AS zoo

OK

SELECT
    zoo.a
FROM foo AS zoo

もしくは

SELECT
    a
FROM foo

Rule_L026 FROM句に存在しないオブジェクト書いちゃだめ

NG : veeは存在しないテーブル

SELECT
    vee.a
FROM foo

OK

SELECT
    a
FROM foo

Rule_L027 複数のテーブルを参照するときは、修飾子必要!

NG

SELECT a, b
FROM foo
LEFT JOIN vee ON vee.a = foo.a

OK

SELECT foo.a, vee.b
FROM foo
LEFT JOIN vee ON vee.a = foo.a

Rule_L028 修飾子は全部つけるかつけないか

NG

SELECT
    a,
    foo.b
FROM foo

OK

SELECT
    a,
    b
FROM foo

or

SELECT
    foo.a,
    foo.b
FROM foo

Rule_L029 予約語を修飾子に使わない!

NG

SELECT
    sum.a
FROM foo AS sum

Rule_L030 関数名も大文字小文字を統一する

NG : sum(小文字)とSUM(大文字)

SELECT
    sum(a) AS aa,
    SUM(b) AS bb
FROM foo

Rule_L031 FROM句とJOIN句でのテーブル別名は使わない

NG

SELECT
    COUNT(o.customer_id) as order_amount,
    c.name
FROM orders as o
JOIN customers as c on o.id = c.user_id

OK

SELECT
    COUNT(orders.customer_id) as order_amount,
    customers.name
FROM orders
JOIN customers on orders.id = customers.user_id

-- Self-join will not raise issue

SELECT
    table1.a,
    table_alias.b,
FROM
    table1
    LEFT JOIN table1 AS table_alias ON
        table1.foreign_key = table_alias.foreign_key

Rule_L032 USINGはできるだけ使わない

NG (特にSnowflake)

SELECT
    table_a.field_1,
    table_b.field_2
FROM
    table_a
INNER JOIN table_b USING (id)

OK

SELECT
    table_a.field_1,
    table_b.field_2
FROM
    table_a
INNER JOIN table_b
    ON table_a.id = table_b.id

Rule_L033 UNIONには、DISTINCTかALLをつけるべし

NG

SELECT a, b FROM table_1
UNION
SELECT a, b FROM table_2

OK : UNIONは、デフォルトでALLの挙動

SELECT a, b FROM table_1
UNION DISTINCT
SELECT a, b FROM table_2

Rule_L034 *をつかうなら先頭に

NG

select
    a,
    *,
    row_number() over (partition by id order by date) as y,
    b
from x

OK

select
    *,
    a,
    b,
    row_number() over (partition by id order by date) as y
from x

Rule_L035 case whenにelse nullは冗長なので不要

NG

select
    case
        when name like '%cat%' then 'meow'
        when name like '%dog%' then 'woof'
        else null
    end
from x

OK

select
    case
        when name like '%cat%' then 'meow'
        when name like '%dog%' then 'woof'
    end
from x

Rule_L036 SELECT区の複数カラム指定は改行すべし

NG

select a, b
from foo

OK

select
    a,
    b
from foo

指定カラムが一つの場合は
OK

SELECT a
FROM foo

Rule_L037 ORDER BYでは、指定カラムそれぞれにASC,DESCを必ずつけるべし

NG

SELECT
    a, b
FROM foo
ORDER BY a, b DESC

OK

SELECT
    a, b
FROM foo
ORDER BY a ASC, b DESC

Rule_L038 SELECTの最後に「,」があるのはNG

NG

SELECT
    a,
    b,
FROM foo

Rule_L039 不要な空白は除去しましょう

NG

SELECT
    a,        b
FROM foo

OK

SELECT
    a, b
FROM foo

Rule_L040 null, true, falseは大文字or小文字に揃えるべし

NG

select
    a,
    null,
    TRUE,
    false
from foo

OK

select
    a,
    NULL,
    TRUE,
    FALSE
from foo

-- Also good

select
    a,
    null,
    true,
    false
from foo

Rule_L041 SELECT修飾子(DISTINCTなど)はSELECTと同一行に

NG

select
    distinct a,
    b
from x

OK

select distinct
    a,
    b
from x

Rule_L042 JOIN句にサブクエリはだめ、やるならWITH句(CTEs)

Config : forbid_subquery_in

  • join (デフォルト)
  • from
  • both

NG

select
    a.x, a.y, b.z
from a
join (
    select x, z from b
) using(x)

OK

with c as (
    select x, z from b
)
select
    a.x, a.y, c.z
from a
join c using(x)

Rule_L043 不要なCASE文はかかない!

NG

select
    case
        when fab > 0 then true
        else false
    end as is_fab
from fancy_table

-- COALESCE使えばもっと簡単にかける

select
    case
        when fab is null then 0
        else fab
    end as fab_clean
from fancy_table

-- null の場合に、nullを返すみたいな冗長な場合

select
    case
        when fab is null then null
        else fab
    end as fab_clean
from fancy_table

OK

select
    coalesce(fab > 0, false) as is_fab
from fancy_table

-- NULLを別にする場合

select
    coalesce(fab, 0) as fab_clean
from fancy_table

-- NULLをNULLで返す場合はそもそもCASE文いらない

select fab as fab_clean
from fancy_table

Rule_L044 クエリの結果、カラムの数が不明な場合はNG

NG

WITH cte AS (
    SELECT * FROM foo
)

SELECT * FROM cte
UNION
SELECT a, b FROM t

OK : これは一例、UNION使ってるのに前と後ろでカラム数が違う ことがあり得る

WITH cte AS (
    SELECT * FROM foo
)

SELECT a, b FROM cte
UNION
SELECT a, b FROM t

Rule_L045 使ってないCTEは定義しない!

NG

WITH cte1 AS (
  SELECT a
  FROM t
),
cte2 AS (
  SELECT b
  FROM u
)

SELECT *
FROM cte1

Rule_L046 Jinjaのタグは、左右に空白一つずつ

NG

SELECT {{    a     }} from {{ref('foo')}}

OK

SELECT {{ a }} from {{ ref('foo') }};
 SELECT {{ a }} from {{
     ref('foo')
 }};

Rule_L047 行数をカウントするときはCOUNT(*)を使うべし

OK

select
    count(*)
from table_a

prefer_count_1, prefer_count_0が指定されていると、COUNT(1)、COUNT(0)が使われる

Rule_L048 引用符「'」の前後に空白一文字必要

NG

SELECT
    'foo'AS bar
FROM foo

OK

SELECT
    'foo' AS bar
FROM foo

Rule_L049 NULLかどうかは、IS NULL or IS NOT NULL

NG

SELECT
    a
FROM foo
WHERE a = NULL

OK

SELECT
    a
FROM foo
WHERE a IS NULL

Rule_L050 ファイルは空行や空白で始まるべからず

NG

^

 SELECT
     a
 FROM foo

 -- いきなりインデントも禁止

 ••••SELECT
 ••••a
 FROM
 ••••foo

Rule_L051 JOINには、「INNER」「LEFT/RIGHT/FULL OUTER」を明記すべし

NG

SELECT
     foo
 FROM bar
 JOIN baz;

OK

SELECT
     foo
 FROM bar
 INNER JOIN baz;

Rule_L052 ;で終わるべし

NG

SELECT
     a
 FROM foo

 ;

 SELECT
     b
 FROM bar••;

OK

 SELECT
     a
 FROM foo;

Rule_L053 TOPレベルのSQLは()で囲まない

NG

 (SELECT
     foo
 FROM bar)

OK

SELECT
     foo
 FROM bar

Rule_L054 GROUP BYの記述はカラム名 or ポジション表記(1,2...)のいずれかに統一

NG

SELECT
     foo,
     bar,
     sum(baz) AS sum_value
 FROM fake_table
 GROUP BY
     foo, 2;

Rule_L055 RIGHT JOINは使わない、LEFT  JOINにする

NG

SELECT
     foo.col1,
     bar.col2
 FROM foo
 RIGHT JOIN bar
     ON foo.bar_id = bar.id;

OK

SELECT
     foo.col1,
     bar.col2
 FROM bar
 LEFT JOIN foo
     ON foo.bar_id = bar.id;

Rule_L056 SP_プレフィックスは使わない( T-SQLのストアドプロシージャには)

NG

CREATE PROCEDURE dbo.sp_pull_data
 AS
 SELECT
     ID,
     DataDate,
     CaseOutput
 FROM table1

Rule_L057 識別子に特殊文字を使わない(>とか)

NG

CREATE TABLE DBO.ColumnNames
(
    [Internal Space] INT,
    [Greater>Than] INT,
    [Less<Than] INT,
    Number# INT
)

OK

CREATE TABLE DBO.ColumnNames
(
    [Internal_Space] INT,
    [GreaterThan] INT,
    [LessThan] INT,
    NumberVal INT
)

Rule_L058 CASE文のネストはばらしすべし

NG

SELECT
  CASE
    WHEN species = 'Cat' THEN 'Meow'
    ELSE
    CASE
       WHEN species = 'Dog' THEN 'Woof'
    END
  END as sound
FROM mytable

OK

SELECT
  CASE
    WHEN species = 'Cat' THEN 'Meow'
    WHEN species = 'Dog' THEN 'Woof'
  END AS sound
FROM mytable

Rule_L059 無駄に「"」で囲わない

NG

SELECT 123 as "foo"

OK

SELECT 123 as "foo" -- For ANSI, ...
-- or
SELECT 123 as `foo` -- For BigQuery, MySql, ...

Rule_L060 IFNULLNVLの代わりにCOALESCEを使うべし

NG

SELECT ifnull(foo, 0) AS bar,
FROM baz;

SELECT nvl(foo, 0) AS bar,
FROM baz;

OK

SELECT coalesce(foo, 0) AS bar,
FROM baz;

Rule_L061 「同値ではない」には、「!=」を使う、「<>」は使わない

NG

SELECT * FROM X WHERE 1 <> 2;

OK

SELECT * FROM X WHERE 1 != 2;

Rule_L062 使っちゃだめなワードは指定できる

bloced_wordsdeprecated_tableboolを指定している場合
NG

SELECT * FROM deprecated_table WHERE 1 = 1;
CREATE TABLE myschema.t1 (a BOOL);

この場合のOKは

SELECT * FROM another_table WHERE 1 = 1;
CREATE TABLE myschema.t1 (a BOOLEAN);