SQL querying tables
Learn how to use SQL SELECT, FROM, LIMIT, ORDER BY, and AS to query and sort tables.
Learn SQL with MetabaseDownload Metabase for free, or sign up for a free trial of Metabase Cloud
What we’ll cover
- Use
SELECT
to specify the columns you want to get › *
selects all columns ›- Use
FROM
to specify the table or subquery you want to query › - When not aggregating your tables,
LIMIT
rows when developing your queries (so you don’t nuke your database) › - Add comments with
--
; they won’t affect the results, but will help people understand your code › - End each query with a
;
› - Change the names of columns with
AS
› - Sort results with
ORDER BY
, eitherASC
for ascending orDESC
for descending › - Select specific columns using a comma-separated list ›
- Understand SQL casing conventions and when case matters ›
- Sample data from tables using the
MOD
function ›
SQL to get all the rows from a table
If you want to get the whole table and all its rows, like this products
table:
| id | ean | title | category | vendor | price | rating | created_at |
| --- | ------------- | ------------------------- | --------- | ---------------------------- | ----- | ------ | --------------------------- |
| 1 | 1018947080336 | Rustic Paper Wallet | Gizmo | Swaniawski, Casper and Hilll | 29.46 | 4.6 | July 19, 2017, 7:44 PM |
| 2 | 7663515285824 | Small Marble Shoes | Doohickey | Balistreri-Ankunding | 70.08 | 0 | April 11, 2019, 8:49 AM |
| 3 | 4966277046676 | Synergistic Granite Chair | Doohickey | Murray, Watsica and Wunsch | 35.39 | 4 | September 8, 2018, 10:03 PM |
You SELECT
columns FROM
the table, like so:
SELECT
*
FROM
products;
SELECT
is a SQL reserved word that specifies the columns to return. Reserved words are keywords in SQL that have special meanings for the database engines that process the queries.*
is the wildcard operator that tells the database to return all columns from a table. In general, you should only include the exact columns you want in the results. Do not try this with really large tables without limiting your results, unless you want to make everyone else’s day worse.FROM
is a SQL reserved word that tells the database which table (or tables) to look for the columns. Table names must be exact (but casing doesn’t matter).- Note the
;
at the end of the query. Metabase is pretty forgiving about whether you include the semi-colon, but other editors/databases may not be. They’ll look for the semi-colon to know the query is complete.
The order of operations your database engine steps through when processing your query is NOT the same as the order of operations as one reads through the code. In general, you don’t have to think about this, as people have put in an unbelievable number of hours optimizing these query engines.
SQL to add comments to your code
You can (and should) add comments to a query with --
. Here’s that same query, with explanatory comments:
-- Our first query
SELECT
* -- The star means to get all columns
FROM
products; -- The table to query
The database’s query processor knows to ignore anything on a line after --
. In fact, you could put an entire sailboat in your query and the results wouldn’t change:
SELECT
*
FROM
-- An entire sailboat
products;
SQL to only get some rows from the table
You can LIMIT
the results, like so:
SELECT
*
FROM
products
LIMIT -- SQL reserved word
3; -- Only get the first 3 rows
Which will return all columns (*
), but only 3
rows. Where possible, limit rows as you’re developing queries to speed up loading times. Fortunately, Metabase automatically limits results to the first 2,000 rows so people don’t blow up their database. But it’s still good practice.
Limit only affects the number of rows returned. If you’re aggregating data, like counting rows and grouping rows (which we’ll cover later), the database will still count and group all the rows, but only return the number of result rows set by LIMIT
.
SQL to only get some columns
To return specific columns, like only the title
and category
columns:
| title | category |
| ------------------------- | --------- |
| Rustic Paper Wallet | Gizmo |
| Small Marble Shoes | Doohickey |
| Synergistic Granite Chair | Doohickey |
SELECT
each column, in the order you want the columns displayed in the results. Separate columns with a comma (but don’t add a comma at the end of the list), like so:
SELECT
title, -- Names of each column must be exact
category -- No comma at the end of list
FROM
products;
In fact, so many people have been burned by the missing comma error that some people format their SQL like this just to make the commas easier to see (but more so to make the columns easier to comment out as needed):
SELECT
title
,category -- Comma precedes each column except the first column
,vendor -- No comma at the end of list
FROM
products;
SQL to sort results
You can sort the rows of results with ORDER BY
. For example, to sort products by price from lowest to highest:
SELECT
title,
price
FROM
products
ORDER BY -- Sorts results
price ASC; -- By the price column in ascending order
Which returns:
| Title | Price |
| ------------------------ | ----- |
| Mediocre Paper Car | 15.69 |
| Rustic Paper Car | 19.87 |
| Heavy-Duty Copper Gloves | 20.41 |
| Enormous Marble Shoes | 21.42 |
The ASC
keyword is sometimes optional (depending on the database engine), but including ASC
in the ORDER BY
clause makes the code easier to read, and it’ll always work.
To sort in descending order (highest to lowest), add the DESC
keyword:
SELECT
title,
price
FROM
products
ORDER BY
price DESC; -- Sorts in descending order
To sort by multiple columns, for example, first by category
(alphabetically), then by price
within each category (highest to lowest):
SELECT
title,
category,
price
FROM
products
ORDER BY
category ASC, -- Sorts categories alphabetically (note the comma)
price DESC; -- Then sorts prices highest to lowest within each category
You might sometimes see people ordering by numbers, like this:
SELECT
title,
category,
price
FROM
products
ORDER BY
2 ASC, -- Sorts categories alphabetically (note the comma)
3 DESC; -- Then sorts prices highest to lowest within each category
Here the numbers correspond with the column’s ordinal position in the SELECT
statement. With some databases, ordering by position is the only way to order by aliased columns. But if possible, it’s better to include the column names or aliases so people don’t have to bounce back and forth between the SELECT
and ORDER BY
sections when reading the code.
SQL to change the names of the columns
Say your table has column names like title
and category
, but you want each column heading to start with “Product”, like this:
| Product title | Product category |
| ------------------------- | ---------------- |
| Rustic Paper Wallet | Gizmo |
| Small Marble Shoes | Doohickey |
| Synergistic Granite Chair | Doohickey |
To change the name of a column (in the results, not the table itself), use AS
to create an alias for the column, like so:
SELECT
title AS "Product title", -- Note the double quotes, single quotes won't work
category AS "Product category"
FROM
products;
SQL aliases are temporary names for values in a query. Aliases don’t have any effect on the underlying database; aliases only exist in the query itself. You typically use aliases to:
- Improve readability.
- Name column expressions (e.g.,
CONCAT(first_name, ' ', last_name) AS "Full name"
). - Name common table expressions (see CTEs).
- Self-join tables.
SQL casing usually doesn’t matter, except for aliases
Using all caps for SQL’s reserved words is a convention that predates syntax highlighting, but letter case doesn’t matter for reserved words or column names. This query works too:
SeLeCt
*
FrOM
PROdUCTS;
But, you know: don’t. Write queries that people (including you six months from now) can read. So, all-caps or not (SELECT
or select
), be consistent.
Casing does apply to aliases, however, so make sure aliases match case letter for letter (with aliases, "Example"
is not the same as "example"
).
SQL to get a sampling of rows
This will only work if your table has an ID row with a random distribution. You can use the MOD
function (short for modulo) to sample data based on IDs:
SELECT
id,
title,
category
FROM
products
WHERE
-- For this to work, the table's ids must be sequential integers
MOD(id, 10) = 3;
Which returns:
| id | title | category |
|-----|-------------------------------|------------|
| 3 | Synergistic Granite Chair | Doohickey |
| 13 | Synergistic Steel Chair | Gizmo |
| 23 | Fantastic Aluminum Bottle | Widget |
And more rows, with each tenth row having an ID ending in 3. How this works: If the ID were 23, for example, MOD(23, 10)
would return 3, as 23 divided by 10 leaves a remainder of 3, so the 23rd row would be included in the results. That’s only dividing the results by 10, so if the table has a ton of rows, you’d want to increase the divisor’s magnitude: 100, 1000, etc.
This tip is more of a whet-your-appetite-for-what’s-possible-in-SQL kind of thing. We’ll cover SQL functions (like MOD
) in depth later on.