<style> .reveal-up, .reveal-left, .reveal-right, .reveal-stagger > * { opacity: 1 !important; transform: none !important; } </style>
  1. Learn
  2. SQL
  3. Foundations
All lessons in this course

Lesson 3 of 54 15 minBeginner

Your first SELECT: columns, aliases and expressions

Choose columns, rename them, calculate new ones and join text together. Plus the order SQL Server really processes a query in, and why an alias cannot be used in WHERE.

Every query that reads data is a SELECT. Its simplest form names the columns you want and the table they come from. The result is always a new table: rows and columns that exist only until SSMS shows them.

Query.sql
SELECT CategoryId, NameFROM dbo.Categories;
Output
CategoryId  Name
----------  --------
         1  Tools
         2  Building
         3  Timber
         4  Fixings
         5  Paint
         6  Safety
         7  Plumbing

The SELECT list decides the shape of the result: which columns, in what order, with what names. Try it on the Products table:

Interactive

Build a SELECT list

Columns
Query.sql
SELECT Name, PriceFROM dbo.Products;
NamePrice
1Claw hammer18.50
2Cordless drill89.00
3Tape measure 8 m9.75
4Cement 25 kg7.20
5Sand 25 kg4.10
6Timber 2x4 2.4 m6.80
7Plywood sheet 18 mm42.00
8Wood screws (200)11.90
9Wall plugs (100)4.50
10Masonry paint 10 L54.00
11Paint roller set12.50
12Safety goggles6.80
Same 12 rows every time; the SELECT list only decides which 2 columns you see, in the order you list them.

SELECT * and why to avoid it in real code

SELECT * means “every column”. It is perfect for a quick look at a table in SSMS. In application code, list the columns: the query then returns the same shape even after someone adds a column, it reads less data, and anyone reading it can see what is used.

Aliases: renaming columns

AS gives a column a new name in the result. The table is not changed. An alias with a space or a reserved word needs square brackets.

Query.sql
SELECT Name AS Product, Price AS [Unit price], UnitFROM dbo.ProductsWHERE CategoryId = 3;
Output
Product              Unit price  Unit
-------------------  ----------  -----
Timber 2x4 2.4 m           6.80  each
Plywood sheet 18 mm       42.00  sheet

Calculated columns

A SELECT list can contain expressions, worked out for every row as the result is produced. Nothing is stored. Here is the value of the stock on the shelf for each paint product:

Query.sql
SELECT Name, Price, Stock, Price * Stock AS StockValueFROM dbo.ProductsWHERE CategoryId = 5;
Output
Name                Price  Stock  StockValue
------------------  -----  -----  ----------
Masonry paint 10 L  54.00     25     1350.00
Paint roller set    12.50     30      375.00

Arithmetic uses + - * / and % (remainder). The usual precedence applies: *, / and % before + and -, with parentheses to change it.

Joining text together

Use + or CONCAT to join strings. CONCAT also converts numbers for you and treats NULL as empty text, which + does not (more on NULL in two lessons). You can also put fixed values, called literals, in the SELECT list.

Query.sql
SELECT FirstName + N' ' + LastName AS FullName,       CONCAT(FirstName, N' joined on ', JoinedOn) AS Note,       N'BuildMart' AS ShopFROM dbo.CustomersWHERE CustomerId <= 3;
Output
FullName     Note                        Shop
-----------  --------------------------  ---------
Asha Patel   Asha joined on 2023-03-02   BuildMart
Ben Carter   Ben joined on 2023-05-19    BuildMart
Chloe Evans  Chloe joined on 2023-06-07  BuildMart

CONCAT turned the JoinedOn date into text by itself. With +, SQL Server would try to turn the text into a date instead, and fail.

A SELECT does not even need a table. Without FROM it returns a single row, which makes SQL Server a handy calculator:

Query.sql
SELECT 2 + 3 * 4 AS Answer, (2 + 3) * 4 AS WithBrackets, 17 % 5 AS Remainder;
Output
Answer  WithBrackets  Remainder
------  ------------  ---------
    14            20          2

The order SQL Server reads a query in

You write SELECT first, but it is not processed first. The logical processing order is:

  1. FROM: which table(s) the rows come from.
  2. WHERE: keep only the rows that pass the test.
  3. SELECT: work out the columns and expressions, and apply aliases.
  4. ORDER BY: sort the result (lesson 6).

Because WHERE runs before SELECT, an alias made in the SELECT list does not exist yet when WHERE is checked:

Query.sql
SELECT Name, Price * Stock AS StockValueFROM dbo.ProductsWHERE StockValue > 1000;
Output
Msg 207, Level 16, State 1, Line 1
Invalid column name 'StockValue'.

Repeat the expression in the WHERE clause instead (WHERE Price * Stock > 1000). ORDER BY runs after SELECT, so it is the one clause where the alias does work.

Style that pays off

  • Write keywords in capitals (SELECT, FROM, WHERE) and names as they are defined. SQL Server does not care; readers do.
  • Put each clause on its own line.
  • End statements with a semicolon. It is optional for most statements today, but required before some (such as a WITH common table expression), and Microsoft recommends it.
  • Comment with -- to the end of the line, or /* … */ across lines.
Quick check

Which clause is logically processed first?

Quick check

What does SELECT Price * Stock AS StockValue FROM dbo.Products; change in the Products table?

Practice

BuildMart charges 20% VAT on top of its prices. For every product in category 1 (Tools), show the Name, the Price, and the price including VAT as PriceIncVat.

Show a hint

Multiply the price by 1.2 in the SELECT list and give it an alias. Filter with WHERE CategoryId = 1.

Show the solution
Solution.sql
SELECT Name, Price, Price * 1.2 AS PriceIncVatFROM dbo.ProductsWHERE CategoryId = 1;
Output
Name              Price  PriceIncVat
----------------  -----  -----------
Claw hammer       18.50       22.200
Cordless drill    89.00      106.800
Tape measure 8 m   9.75       11.700

Remember

  • The SELECT list decides the shape of the result: which columns, in what order, with what names.
  • SELECT * is for quick looks; list columns in real code.
  • AS renames a column in the result only; use [brackets] for names with spaces or reserved words.
  • Expressions such as Price * Stock are calculated per row and stored nowhere.
  • Logical order: FROM → WHERE → SELECT → ORDER BY, so aliases cannot be used in WHERE.
0 of 54 lessons completed