Python · SQL · Web Dev · Java · AI/ML tracks launching soon — your one platform for all of IT
Beginner

Renaming Columns — AS (Aliases)

Give columns and tables readable names, understand where aliases can and cannot be used, and write queries that communicate clearly to every reader

7–10 min April 2026
Section 2 · Reading Data — SELECT

// Part 01

What an Alias Is and Why It Exists

Every column in a SQL result has a header — the name that appears at the top of that column. Without aliases, that header is whatever the database decides to call it: the raw column name for simple selections, or the full expression text for calculated columns. The results are technically correct but often unreadable.

Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…
Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…

An alias is a temporary name you assign to a column or table for the duration of a query. It exists only in the result — the database schema is never changed. The AS keyword introduces the alias, though AS is optional in most databases (a space works too — but AS is always clearer and recommended).

// Part 02

Column Aliases — Naming Your Output Columns

A column alias renames a column in the query result. It is placed immediately after the column expression using AS.

Column alias syntax
-- Syntax:
expression AS alias_name

-- AS is optional (but always use it for clarity):
expression alias_name    -- works but hard to read

-- Examples:
first_name AS name
unit_price AS price
unit_price - cost_price AS profit
ROUND(salary / 12, 2) AS monthly_salary

Aliasing raw columns

Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…
Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…

Aliasing calculated columns

This is where aliases are most essential. Without an alias, a calculated column's header is the full expression — unreadable in reports and unusable in application code that references columns by name.

Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…

// Part 03

Alias Naming Rules — What Is and Is Not Allowed

Alias names follow specific rules. Violating them causes syntax errors or unexpected behaviour.

RuleValidInvalidNote
No spaces (unquoted)margin_pctmargin pctUse underscore instead of space
No reserved words (unquoted)order_countcount"count" needs quotes — COUNT is a SQL function
No special chars (unquoted)gst_pricegst-priceHyphen is interpreted as subtraction
Start with letter or underscore_total, total123totalCannot start with a digit
Quoted aliases — anything goes"Margin %"Double quotes allow spaces, special chars, reserved words
Case sensitivityMargin, margin, MARGINUnquoted aliases are case-insensitive in most databases

Quoted aliases — for special characters and spaces

When you need spaces, special characters, or SQL reserved words in an alias, wrap it in double quotes (PostgreSQL/standard SQL) or backticks (MySQL).

Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…
🎯 Pro Tip
For programmatic use — when application code reads column names — use simple snake_case aliases without quotes: margin_pct, total_revenue, order_count. For human-facing reports and dashboards — use quoted aliases with spaces and proper capitalisation: "Margin %", "Total Revenue", "Order Count". Match the alias style to the consumer of the query.

// Part 04

Where Aliases Can and Cannot Be Used — The Execution Order Rule

This is the most important thing to understand about aliases. Because SQL clauses are executed in a specific order — and aliases are defined in SELECT — aliases can only be referenced in clauses that execute after SELECT.

SQL execution order — where aliases exist
-- Execution order:
-- 1. FROM        ← aliases DO NOT exist yet
-- 2. WHERE       ← aliases DO NOT exist yet
-- 3. GROUP BY    ← aliases DO NOT exist yet (in most databases)
-- 4. HAVING      ← aliases DO NOT exist yet (in most databases)
-- 5. SELECT      ← aliases ARE DEFINED HERE
-- 6. ORDER BY    ← aliases CAN BE USED HERE ✓
-- 7. LIMIT       ← aliases CAN BE USED HERE ✓

WHERE cannot use SELECT aliases

Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…
Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…

ORDER BY CAN use SELECT aliases

Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…

GROUP BY — database-dependent

GROUP BY executes before SELECT in the logical order, so technically aliases should not be available. However, MySQL and DuckDB (this playground) allow GROUP BY to reference SELECT aliases as a convenience extension. PostgreSQL follows the standard strictly — GROUP BY cannot use SELECT aliases. Always repeat the expression in GROUP BY for cross-database compatibility.

GROUP BY — safe cross-database approach
-- Safe: repeat the expression in GROUP BY (works everywhere)
SELECT
  EXTRACT(MONTH FROM order_date)  AS order_month,
  COUNT(*)                        AS order_count
FROM orders
GROUP BY EXTRACT(MONTH FROM order_date)   -- repeat expression
ORDER BY order_month;

-- MySQL / DuckDB only: GROUP BY alias (not portable)
SELECT
  EXTRACT(MONTH FROM order_date)  AS order_month,
  COUNT(*)                        AS order_count
FROM orders
GROUP BY order_month   -- works in MySQL/DuckDB, fails in PostgreSQL
ORDER BY order_month;

// Part 05

Table Aliases — Shorter Names for Tables

Aliases are not just for columns — you can also alias tables. Table aliases give a table a short name for the duration of the query. This is most useful in JOIN queries where you reference the same table multiple times, or when table names are long and repetitive.

Table alias syntax
-- Syntax: table_name AS alias  (AS is optional for tables too)
FROM customers AS c
FROM customers c          -- same thing, AS omitted

FROM orders AS o
FROM order_items AS oi
FROM products AS p

-- Then reference columns using alias.column_name:
SELECT c.first_name, o.total_amount
FROM customers AS c
JOIN orders AS o ON c.customer_id = o.customer_id
Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…
Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…

Self-join requires table aliases

When a table joins itself (a self-join — used for hierarchies like manager/employee), aliases are not just convenient — they are required. Without aliases, there is no way to distinguish the two instances of the same table.

Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…

// Part 06

Subquery Aliases — Every Subquery Needs a Name

When you use a subquery in the FROM clause (a derived table), it must be given an alias. The database needs to refer to the subquery result as if it were a table, and it cannot do so without a name.

Subquery alias — required syntax
-- Subquery in FROM must have an alias
SELECT *
FROM (
  SELECT customer_id, COUNT(*) AS order_count
  FROM orders
  GROUP BY customer_id
) AS customer_orders          -- alias required — cannot omit this
WHERE order_count > 2;

-- Without the alias: ERROR
SELECT *
FROM (
  SELECT customer_id, COUNT(*) AS order_count
  FROM orders
  GROUP BY customer_id
)                              -- ERROR: subquery must have an alias
WHERE order_count > 2;
Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…

// Part 07

Alias Conventions — How Professional Teams Name Things

Consistent alias naming conventions make queries readable across a team. Here are the conventions used at most Indian tech companies and data teams.

Column alias conventions

snake_case for programmatic use
margin_pcttotal_revenueorder_countavg_delivery_days
When application code or downstream SQL will reference the column name
Quoted Title Case for reports
"Margin %""Total Revenue""Order Count""Avg Delivery Days"
When the result goes to a spreadsheet, dashboard, or human-readable report
Prefix for aggregates
total_amountavg_pricemax_salarymin_datecount_orders
Prefix with the aggregate function name — makes it immediately clear what the number represents
Suffix for percentages and rates
margin_pctdiscount_ratecompletion_pctgrowth_rate
_pct for percentages, _rate for rates — prevents confusion with raw count/amount columns

Table alias conventions

Table alias conventions used in professional SQL
-- Short first-letter or first-two-letter aliases are standard:
customers   → c
orders      → o
order_items → oi
products    → p
stores      → s
employees   → e

-- For self-joins, use descriptive aliases:
employees AS emp   -- the employee
employees AS mgr   -- the manager

-- For subqueries, use descriptive names:
) AS monthly_totals
) AS customer_orders
) AS ranked_products

-- Avoid single letters for subqueries — they are too cryptic:
) AS t    -- what is t? unclear
) AS x    -- even worse

// Part 08

Practical Alias Examples — Complete FreshCart Queries

Here are complete, well-aliased queries for real FreshCart reporting scenarios.

Customer summary report

Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…

Product catalogue with computed fields

Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…

Order analysis report

Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…

// Part 09

What This Looks Like at Work

You are a data analyst at Amazon's seller analytics team. Sellers use a dashboard to monitor their product performance. The dashboard pulls data from a SQL query that you maintain. The query was written six months ago by a colleague who has since left — and it has no aliases anywhere.

9:00 AM
You inherit the query
The original query looks like this — technically correct but completely unreadable:
The original query — no aliases, unreadable
SELECT product_name, unit_price, cost_price,
unit_price - cost_price,
ROUND((unit_price - cost_price) / unit_price * 100, 1),
ROUND(unit_price * 1.18, 2),
CASE WHEN in_stock = true THEN 'Available' ELSE 'Unavailable' END
FROM products
ORDER BY ROUND((unit_price - cost_price) / unit_price * 100, 1) DESC;
9:15 AM
You add aliases — 10 minutes of work
The refactored query is identical in output but completely self-documenting:
Loading FreshCart DB…
Ctrl + Enter to run
Loading FreshCart database in your browser…
9:30 AM
Impact is immediate
The dashboard team replaces their hardcoded column index references (column[3], column[4]) with named references (margin_pct, mrp_incl_gst). A new analyst can read the query and understand every column without asking you. When the product manager asks "what does column 5 mean?" — that question never comes again.

🎯 Pro Tip

Every query you write will eventually be read by someone else — a colleague, a future version of yourself, or a new hire debugging an issue at 2 AM. Aliases cost 10 seconds to write and save hours of confusion. Make aliasing every computed column and every table in a JOIN a non-negotiable personal standard. The best SQL writers are distinguished not just by correctness but by clarity.

// Part 10

Interview Prep — 5 Questions With Complete Answers

Q: What is a SQL alias and what are the two types?

A SQL alias is a temporary name assigned to a column expression or a table for the duration of a query. It exists only in the query output — it does not change the database schema, the table structure, or the column names stored in the database. The AS keyword introduces the alias: expression AS alias_name. AS is optional in most databases but always recommended for readability.

The two types are column aliases and table aliases. A column alias renames a column in the result set — it controls the header name that appears in the output. Column aliases are most important for calculated columns, where without an alias the header would be the full expression text: unit_price - cost_price as a column header versus profit. Column aliases are also used to rename existing columns to more readable names for specific reports or applications.

A table alias gives a table a shorthand name for use throughout the query. Table aliases serve two purposes: they shorten long table names in queries that reference the same table many times, and they are essential in JOIN queries to distinguish which table each column comes from when multiple tables share the same column name. In self-joins — where a single table appears twice in the FROM clause — table aliases are required because the database needs two distinct names to refer to the two instances.

Q: Why can you use a column alias in ORDER BY but not in WHERE?

The answer comes from SQL's logical execution order. SQL clauses are not executed in the order they are written. The actual execution order is: FROM (identify source tables), WHERE (filter rows), GROUP BY (group filtered rows), HAVING (filter groups), SELECT (compute and name output columns), ORDER BY (sort the result), LIMIT (truncate to N rows).

Column aliases are defined during the SELECT step — step 6 in this sequence. WHERE is step 2 and GROUP BY is step 3. Since both execute before SELECT, aliases do not yet exist when WHERE and GROUP BY run. Referencing an alias in WHERE — WHERE profit > 50, where profit is a SELECT alias — would ask the database to use a name that has not been defined yet, which is why it fails with "column does not exist."

ORDER BY, however, executes after SELECT — step 7. By that point the SELECT has already run and all aliases have been defined. The database knows what profit means because SELECT has already computed and named it. This is why ORDER BY margin_pct DESC works correctly. The practical implication: repeat the full expression in WHERE and GROUP BY, but use the cleaner alias in ORDER BY. Some databases (MySQL, DuckDB) extend the standard and allow aliases in GROUP BY as a convenience — but this is not portable and should be avoided in code intended to run on multiple database systems.

Q: What happens if you do not alias a calculated column?

Without an alias, a calculated column's header in the result is whatever the database chooses to call it — typically the full expression text. In PostgreSQL, unit_price - cost_price appears as a column named exactly "?column?" or "unit_price - cost_price". In MySQL it might be "unit_price - cost_price". ROUND((unit_price - cost_price) / unit_price * 100, 1) might appear as a column named with the entire expression.

This creates three practical problems. First, readability — a column named "ROUND((unit_price - cost_price) / unit_price * 100, 1)" in a report is useless to any business user. Second, application code — most application frameworks reference columns by name. A Python script doing result['margin_pct'] works. result['ROUND((unit_price - cost_price) / unit_price * 100, 1)'] does not. Third, portability — the auto-generated column name varies by database system, so the same query produces differently named columns on PostgreSQL and MySQL, breaking any code that references the column name.

The professional standard: every calculated column, every CASE expression, every aggregate function result, and every concatenated string expression should have an explicit alias. This applies even when you think only you will run the query — the next person to run it (or future you) will thank the aliases.

Q: When is a table alias required vs just recommended?

Table aliases are required in two specific situations. First, self-joins — when a table is joined to itself, the database needs two distinct names to refer to the two instances. Without aliases, FROM employees JOIN employees produces an error because there is no way to distinguish the two copies of the table. FROM employees AS e JOIN employees AS m provides the two names needed: e for the employee record and m for the manager record. This pattern is used for any hierarchy stored in a single table: org charts, category trees, location hierarchies.

Second, subquery aliases — any subquery in the FROM clause must be given an alias. The database treats the subquery result as a temporary table and needs a name to refer to it. FROM (SELECT ...) as an unnamed subquery produces a syntax error. FROM (SELECT ...) AS subq gives the derived table the name subq, which can then be referenced in the outer query's WHERE, JOIN ON, and SELECT clauses.

Table aliases are recommended (but not required) in all JOIN queries involving multiple tables. Without aliases, every column reference must be fully qualified with the table name: customers.customer_id, orders.order_id, customers.first_name — verbose and repetitive. With aliases c, o, the same references become c.customer_id, o.order_id, c.first_name — much more concise. Professional SQL writers use table aliases in every multi-table query as a matter of course, not just when required.

Q: Can you use the same alias name twice in one query?

For column aliases — no, and it should not be done. If you define two columns with the same alias name in the same SELECT, the behaviour is database-specific. PostgreSQL returns both columns with the same name, which confuses application code that reads columns by name. Most other databases exhibit similar undefined or database-specific behaviour. The practical rule: every column alias in a SELECT must be unique. Column aliases are the names application code uses to access values, and duplicate names make it impossible to reliably access either value.

For table aliases — no, for the same reason. Two tables with the same alias in the FROM clause would create ambiguity about which table a column reference belongs to. FROM customers AS c JOIN orders AS c creates an error — the database cannot determine whether c.customer_id refers to the customers or orders alias. All table aliases in a FROM clause must be distinct.

The only scenario where the same alias name can appear is in separate subqueries at different levels of nesting. A subquery alias named totals does not conflict with another subquery alias also named totals in a different part of the query, because each alias is scoped to its own level of the query. However, this is still bad practice — use descriptive, unique names for every alias in the query regardless of scope. Repeated alias names, even in different scopes, create confusion for anyone reading the query.

// Part 11

Errors You Will Hit — And Exactly Why They Happen

ERROR: column 'profit' does not exist — WHERE profit > 50

Cause: You used a SELECT alias in a WHERE clause. WHERE executes before SELECT in the logical execution order, so when WHERE evaluates 'profit > 50', the alias 'profit' has not been defined yet — it will be defined later during SELECT. The database sees 'profit' in WHERE and looks for a column with that name in the table, finds none, and throws a column-not-found error.

Fix: Repeat the full expression in WHERE: WHERE (unit_price - cost_price) > 50. Do not use the alias. The alias is only available in ORDER BY (which runs after SELECT). If you find yourself repeating a complex expression many times, consider using a CTE (WITH clause, Module 55) or a subquery to define the calculation once and reference the alias in the outer query.

ERROR: subquery in FROM must have an alias

Cause: You used a subquery in the FROM clause without giving it an alias. The database needs to treat the subquery result as a temporary table and reference it by name in the rest of the query. Without an alias, the database has no name for the derived table and cannot proceed.

Fix: Add AS alias_name immediately after the closing parenthesis of the subquery: FROM (SELECT ... FROM ...) AS my_subquery. The alias name can be anything valid — use something descriptive that explains what the subquery contains: customer_orders, monthly_totals, ranked_products. Then reference the subquery's columns using alias.column_name in the outer SELECT and WHERE.

ERROR: syntax error at or near 'AS' — FROM customers AS

Cause: The table alias declaration is incomplete — AS appears but the alias name is missing. This happens when an alias is started but not finished, often from a copy-paste error or mid-edit save. AS must be followed immediately by the alias name with no other keywords between them.

Fix: Complete the alias: FROM customers AS c. If you do not want a table alias at all, remove the AS entirely: FROM customers. Check that no SQL keywords accidentally ended up where the alias name should be — FROM customers AS WHERE would trigger this error because WHERE is a SQL keyword, not a valid alias name (unquoted).

Column headers show expression text instead of alias name — output shows 'unit_price - cost_price' as header

Cause: You forgot to add an AS alias to a calculated column. The database auto-generates a column name from the expression, which varies by database: PostgreSQL might show '?column?', MySQL shows the full expression text, DuckDB shows '(unit_price - cost_price)'. This is not an error — it is the expected behaviour without an alias.

Fix: Add AS alias_name after the expression: unit_price - cost_price AS profit. Always alias every calculated column, every aggregate function result, and every CASE expression. Build this as a habit rather than a correction — it prevents the problem entirely. If you are working from a query someone else wrote and cannot modify it, most SQL clients allow you to rename columns in the result view — but the SQL itself should have proper aliases.

GROUP BY 1 sorts by wrong column after adding a new column to SELECT

Cause: You used a positional reference in GROUP BY (GROUP BY 1, GROUP BY 2) instead of the column name or alias. When you later add a new column to the SELECT list before the grouped column, the position numbers shift — GROUP BY 1 now refers to the newly added first column, not the intended column. The query runs without error but groups on the wrong column, producing incorrect results.

Fix: Always use the column name or expression in GROUP BY, never positional references: GROUP BY product_name instead of GROUP BY 1. If you need to group by an expression, repeat the expression: GROUP BY EXTRACT(MONTH FROM order_date). This makes the GROUP BY clause self-documenting and immune to SELECT list reordering. The same applies to ORDER BY — avoid ORDER BY 1, ORDER BY 2 in production queries; use column names or aliases instead.

Try It Yourself

Write a clean, well-aliased query for the FreshCart monthly business review. The query should show: each store's ID (aliased as 'store'), the store's city, total number of orders placed (aliased as 'total_orders'), total revenue from delivered orders only (aliased as 'delivered_revenue'), and average order value across all orders (aliased as 'avg_order_value', rounded to 2 decimal places). Join the stores and orders tables. Group by store. Sort by delivered_revenue descending.

🎯 Key Takeaways

  • An alias is a temporary name for a column or table, defined with AS. It exists only in the query output — the database schema is never changed.
  • Column aliases rename output column headers. They are most essential for calculated columns — without them, the header is the full expression text, which is unreadable and unusable in application code.
  • Table aliases give tables a shorthand name. They are required in self-joins (a table joined to itself) and for subqueries in FROM. They are strongly recommended in all multi-table JOIN queries.
  • Column aliases are defined during SELECT (step 6 of execution). They can only be referenced in clauses that run after SELECT — ORDER BY works, WHERE and GROUP BY do not.
  • To filter on a calculated value, repeat the expression in WHERE — not the alias: WHERE (unit_price - cost_price) > 50, not WHERE profit > 50.
  • Subquery aliases are mandatory. Every subquery in FROM must be named: FROM (SELECT ...) AS subq_name. Without the alias, the query throws a syntax error.
  • Quoted aliases (double quotes in PostgreSQL, backticks in MySQL) allow spaces, special characters, and SQL reserved words: AS "Margin %", AS "Order Count".
  • Alias naming conventions: snake_case for programmatic use (margin_pct, total_revenue), quoted Title Case for human-readable reports ("Margin %", "Total Revenue"). Prefix aggregates: total_, avg_, max_, min_.
  • Never use positional references in GROUP BY (GROUP BY 1) — they break when columns are reordered. Always use column names or repeat the expression.
  • Every calculated column, every aggregate result, every CASE expression, and every concatenated string in a production query should have an explicit alias. This is not optional — it is the professional standard.

What comes next

In Module 14, you learn pattern matching with LIKE and wildcards — finding rows that match a pattern rather than an exact value. This is how you search for emails by domain, product names by brand prefix, or any partial text match.

Module 14 → Pattern Matching — LIKE & Wildcards
Share

Discussion

0

Have a better approach? Found something outdated? Share it — your knowledge helps everyone learning here.

Continue with GitHub
Loading...