Skip to content

Aliasing Rules

This section contains 10 rule(s) related to aliasing.

Rule Summary

CodeNameAliasesFix Compatible
AL01aliasing.tableL011
AL02aliasing.columnL012
AL03aliasing.expressionL013
AL04aliasing.unique.tableL020
AL05aliasing.unusedL025
AL06aliasing.lengthL066
AL07aliasing.forbidL031
AL08aliasing.unique.column-
AL09aliasing.self_alias.column-
AL10aliasing.required-

AL01: aliasing.table

Implicit/explicit aliasing of table.

PropertyValue
Namealiasing.table
AliasesL011
Groupsall, aliasing
Auto-fixableYes ✅

Aliasing of table to follow preference (requiring an explicit AS is the default).

Anti-pattern

In this example, the alias voo is implicit.

sql
SELECT
    voo.a
FROM foo voo

Best practice

Add AS to make it explicit.

sql
SELECT
    voo.a
FROM foo AS voo

Configuration

OptionDescription
aliasingShould alias have an explicit AS or is implicit aliasing required? Must be one of ['implicit', 'explicit'].

AL02: aliasing.column

Implicit/explicit aliasing of columns.

PropertyValue
Namealiasing.column
AliasesL012
Groupsall, core, aliasing
Auto-fixableYes ✅

Aliasing of columns to follow preference (explicit using an AS clause is default).

Anti-pattern

In this example, the alias for column a is implicit.

sql
SELECT
    a alias_col
FROM foo

Best practice

Add AS to make it explicit.

sql
SELECT
    a AS alias_col
FROM foo

Configuration

OptionDescription
aliasingShould alias have an explicit AS or is implicit aliasing required? Must be one of ['implicit', 'explicit'].

AL03: aliasing.expression

Column expression without alias. Use explicit AS clause.

PropertyValue
Namealiasing.expression
AliasesL013
Groupsall, core, aliasing
Auto-fixableNo ❌

Anti-pattern

In this example, there is no alias for both sums.

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

Best practice

Add aliases.

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

Configuration

OptionDescription
allow_scalarWhether or not to allow a single element in the select clause to be without an alias. Must be one of [True, False].

AL04: aliasing.unique.table

Table aliases should be unique within each clause.

PropertyValue
Namealiasing.unique.table
AliasesL020
Groupsall, core, aliasing, aliasing.unique
Auto-fixableNo ❌

Reusing table aliases is very likely a coding error.

Anti-pattern

In this example, the alias t is reused for two different tables:

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

-- This can also happen when using schemas where the
-- implicit alias is the table name:

SELECT
    a,
    b
FROM
    2020.foo,
    2021.foo

Best practice

Make all tables have a unique alias.

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

-- Also use explicit aliases when referencing two tables
-- with the same name from two different schemas.

SELECT
    f1.a,
    f2.b
FROM
    2020.foo AS f1,
    2021.foo AS f2

AL05: aliasing.unused

Tables should not be aliased if that alias is not used.

PropertyValue
Namealiasing.unused
AliasesL025
Groupsall, core, aliasing
Auto-fixableYes ✅

Anti-pattern

sql
SELECT
    a
FROM foo AS zoo

Best practice

Use the alias or remove it. An unused alias makes code harder to read without changing any functionality.

sql
SELECT
    zoo.a
FROM foo AS zoo

-- Alternatively...

SELECT
    a
FROM foo

Configuration

OptionDescription
alias_case_checkHow to handle comparison casefolding in an alias. Must be one of ['dialect', 'case_insensitive', 'quoted_cs_naked_upper', 'quoted_cs_naked_lower', 'case_sensitive'].

AL06: aliasing.length

Enforce table alias lengths in from clauses and join conditions.

PropertyValue
Namealiasing.length
AliasesL066
Groupsall, core, aliasing
Auto-fixableNo ❌

Anti-pattern

In this example, alias o is used for the orders table.

sql
SELECT
    SUM(o.amount) as order_amount,
FROM orders as o

Best practice

Avoid aliases. Avoid short aliases when aliases are necessary.

See also: AL07.

sql
SELECT
    SUM(orders.amount) as order_amount,
FROM orders

SELECT
    replacement_orders.amount,
    previous_orders.amount
FROM
    orders AS replacement_orders
JOIN
    orders AS previous_orders
    ON replacement_orders.id = previous_orders.replacement_id

Configuration

OptionDescription
max_alias_lengthThe maximum length of an alias to allow without raising a violation. Must be one of range(0, 1000).
min_alias_lengthThe minimum length of an alias to allow without raising a violation. Must be one of range(0, 1000).

AL07: aliasing.forbid

Avoid table aliases in from clauses and join conditions.

PropertyValue
Namealiasing.forbid
AliasesL031
Groupsall, aliasing
Auto-fixableYes ✅

NOTE

This rule was taken from the dbt Style Guide https://github.com/dbt-labs/corp/blob/main/dbt_style_guide.md which notes that:

Avoid table aliases in join conditions (especially initialisms) - it's harder to understand what the table called "c" is compared to "customers".

This rule is controversial and for many larger databases avoiding alias is neither realistic nor desirable. In particular for BigQuery due to the complexity of backtick requirements and determining whether a name refers to a project or dataset so automated fixes can potentially break working SQL code. For most users AL06 is likely a more appropriate linting rule to drive a sensible behaviour around aliasing.

The stricter treatment of aliases in this rule may be useful for more focused projects, or temporarily as a refactoring tool because the fix routine of the rule can remove aliases.

This rule is disabled by default for all dialects it can be enabled with the force_enable = True flag.

Anti-pattern

In this example, alias o is used for the orders table, and c is used for customers table.

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

Best practice

Avoid aliases.

sql
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

Configuration

OptionDescription
force_enableRun this rule even for dialects where this rule is disabled by default. Must be one of [True, False].

AL08: aliasing.unique.column

Column aliases should be unique within each clause.

PropertyValue
Namealiasing.unique.column
Groupsall, core, aliasing, aliasing.unique
Auto-fixableNo ❌

Reusing column aliases is very likely a coding error. Note that while in many dialects, quoting an identifier makes it case-sensitive this rule always compares in a case-insensitive way. This is because columns with the same name, but different case, are still confusing and potentially ambiguous to other readers.

In situations where it is necessary to have columns with the same name (whether they differ in case or not) we recommend disabling this rule for either just the line, or the whole file.

Anti-pattern

In this example, the alias foo is reused for two different columns:

sql
SELECT
    a as foo,
    b as foo
FROM tbl;

-- This can also happen when referencing the same column
-- column twice, or aliasing an expression to the same
-- name as a column:

SELECT
    foo,
    foo,
    a as foo
FROM tbl;

Best practice

Make all columns have a unique alias.

sql
SELECT
    a as foo,
    b as bar
FROM tbl;

-- Avoid also using the same column twice unless aliased:

SELECT
    foo as foo1,
    foo as foo2,
    a as foo3
FROM tbl;

AL09: aliasing.self_alias.column

Column aliases should not alias to itself, i.e. self-alias.

PropertyValue
Namealiasing.self_alias.column
Groupsall, core, aliasing
Auto-fixableYes ✅

Renaming the column to itself is a redundant piece of SQL, which doesn't affect its functionality. This rule only applies when aliasing to an exact copy of the column reference (e.g. foo as foo or "BAR" as "BAR", see note below on more complex examples). Aliases which effectively change the casing of an identifier are still allowed.

NOTE

This rule works in conjunction with references.quoting (RF06) and capitalisation.identifiers (CP02) to handle self aliases with mixed quoting and casing. In the situation that these two rules are not enabled then this rule will only fix the strict case where the quoting and casing of the alias and reference are the same.

If those two rules are enabled, the fixes applied may result in a situation where this rule can kick in as a secondary effect. For example this snowflake_dialect_ref query:

sql
-- Original Query. AL09 will not trigger because casing and
-- quoting are different. RF06 will however fix the unnecessary
-- quoting of "COL".
SELECT "COL" AS col FROM table;
-- After RF06, the query will look like this, at which point
-- CP02 will see the inconsistent capitalisation. Depending
-- on the configuration it will change one of the identifiers.
-- Let's assume the default configuration of "consistent".
SELECT COL AS col FROM table;
-- After CP02, the alias and the reference will be the same
-- and at this point AL09 can take over and remove the alias.
SELECT COL AS COL FROM table;
-- ..resulting in:
SELECT COL FROM table;

This interdependence between the rules, and the configuration options offered by each one means a variety of outcomes can be achieved by enabling and disabling each one. See ruleselection and ruleconfig for more details.

Anti-pattern

Aliasing the column to itself, where not necessary for changing the case of an identifier.

sql
SELECT
    col AS col,
    "Col" AS "Col",
    COL AS col
FROM table;

Best practice

Not to use alias to rename the column to its original name. Self-aliasing leads to redundant code without changing any functionality, unless used to effectively change the case of the identifier.

sql
SELECT
    col,
    "Col"
    COL,
FROM table;

-- Re-casing aliasing is still allowed where necessary, i.e.
SELECT
    col as "Col",
    "col" as "COL"
FROM table;

AL10: aliasing.required

Derived tables must have an alias.

PropertyValue
Namealiasing.required
Groupsall, core, aliasing
Auto-fixableNo ❌

A derived table (subquery in a FROM clause) without an alias will cause a syntax error in most SQL dialects including MySQL, PostgreSQL, and T-SQL.

Anti-pattern

A subquery in a FROM clause without an alias.

sql
SELECT *
FROM (
    SELECT 1 AS a
)

Best practice

Add an alias to the derived table.

sql
SELECT *
FROM (
    SELECT 1 AS a
) AS derived

Released under the MIT License.