SELECT reads data. It is the statement you will write most often.
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
category VARCHAR(50) NOT NULL,
price DECIMAL(8,2) NOT NULL,
stock INT NOT NULL DEFAULT 0,
added_on DATE NOT NULL
);
INSERT INTO products (name, category, price, stock, added_on) VALUES
('Notebook', 'stationery', 80.00, 120, '2026-01-10'),
('Gel Pen', 'stationery', 15.50, 300, '2026-01-12'),
('Backpack', 'bags', 999.00, 25, '2026-02-01'),
('Marker Set', 'stationery', 145.00, 0, '2026-02-15'),
('Desk Lamp', 'home', 650.00, 40, '2026-03-03'),
('Water Bottle', 'home', 220.00, 75, '2026-03-20'),
('Laptop Sleeve', 'bags', 450.00, 18, '2026-04-02'),
('Sticky Notes', 'stationery', 35.00, 210, '2026-04-18');
SELECT * FROM products;
+----+---------------+------------+--------+-------+------------+
| id | name | category | price | stock | added_on |
+----+---------------+------------+--------+-------+------------+
| 1 | Notebook | stationery | 80.00 | 120 | 2026-01-10 |
| 2 | Gel Pen | stationery | 15.50 | 300 | 2026-01-12 |
| 3 | Backpack | bags | 999.00 | 25 | 2026-02-01 |
| 4 | Marker Set | stationery | 145.00 | 0 | 2026-02-15 |
| 5 | Desk Lamp | home | 650.00 | 40 | 2026-03-03 |
| 6 | Water Bottle | home | 220.00 | 75 | 2026-03-20 |
| 7 | Laptop Sleeve | bags | 450.00 | 18 | 2026-04-02 |
| 8 | Sticky Notes | stationery | 35.00 | 210 | 2026-04-18 |
+----+---------------+------------+--------+-------+------------+
8 rows in set
The * means “all columns”. It is convenient for a quick look.
Pick the columns you need
SELECT name, price FROM products;
+---------------+--------+
| name | price |
+---------------+--------+
| Notebook | 80.00 |
| Gel Pen | 15.50 |
| Backpack | 999.00 |
| Marker Set | 145.00 |
| Desk Lamp | 650.00 |
| Water Bottle | 220.00 |
| Laptop Sleeve | 450.00 |
| Sticky Notes | 35.00 |
+---------------+--------+
8 rows in set
List the columns after SELECT, separated by commas. You get exactly those columns, in your order, regardless of the order in the table:
SELECT price, name, category FROM products LIMIT 3;
+--------+----------+------------+
| price | name | category |
+--------+----------+------------+
| 80.00 | Notebook | stationery |
| 15.50 | Gel Pen | stationery |
| 999.00 | Backpack | bags |
+--------+----------+------------+
3 rows in set
The syntax
SELECT column1, column2, ...
FROM table_name;
SELECT says what to show. FROM says where it comes from.
Why not SELECT * in real code
SELECT * is fine for exploring. In application code and in views, it causes real problems:
- Wasted work. It fetches every column, including large
TEXTandBLOBcolumns you do not use. More data is read from disk, sent over the network and held in memory. - Fragile code. If someone adds, removes or reorders a column, your code may break or show the wrong value. A named column fails loudly, and
*fails quietly. - No covering index. A query that needs only
nameandpricemay be answered from an index alone.SELECT *forces a lookup in the table (Covering Indexes). - Unclear intent. A reader cannot tell what the query needs.
- Name clashes in joins. Two tables that both have
idandnamereturn two columns with the same name.
SELECT id, name, price FROM products WHERE category = 'bags';
+----+---------------+--------+
| id | name | price |
+----+---------------+--------+
| 3 | Backpack | 999.00 |
| 7 | Laptop Sleeve | 450.00 |
+----+---------------+--------+
2 rows in set
Name the columns. It takes a few more seconds and saves hours later.
Column names and case
Column names are not case sensitive, and the name that appears in the result header is the one you typed:
SELECT NAME, Price FROM products LIMIT 2;
+----------+-------+
| NAME | Price |
+----------+-------+
| Notebook | 80.00 |
| Gel Pen | 15.50 |
+----------+-------+
2 rows in set
Repeating a column
You can select the same column twice, usually with different aliases:
SELECT name, name AS product_name FROM products LIMIT 2;
+----------+--------------+
| name | product_name |
+----------+--------------+
| Notebook | Notebook |
| Gel Pen | Gel Pen |
+----------+--------------+
2 rows in set
Errors you will see
SELECT nmae FROM products;
ERROR 1054 (42S22): Unknown column 'nmae' in 'field list'
SELECT name FROM product;
ERROR 1146 (42S02): Table 'learn.product' doesn't exist
The first is a mistyped column (error 1054), and the second a mistyped table (error 1146). Read the message: it names what MySQL could not find.
Quick look at a table
SELECT * FROM products LIMIT 5; shows the first rows safely. Always add LIMIT when you explore a table, because a SELECT * on a table with 50 million rows will try to return all of them.