The SELECT statement is the SQL DML command for retrieving rows from one or more tables. Nearly every interactive query is some variant of SELECT some_columns FROM some_table WHERE some_condition.
The simplest form pulls named columns from a single table:
SELECT first_name, last_name FROM employees;This returns every row in employees, but only the two named columns. To get every column, use *:
SELECT * FROM employees;A WHERE clause narrows down which rows are returned (see WHERE clause):
SELECT * FROM employees
WHERE first_name = 'Khalid' OR first_name = 'Maris';String comparison case-sensitivity depends on the dialect and collation. MySQL’s default collations are case-insensitive (_ci) so 'khalid' = 'Khalid' is true. PostgreSQL is case-sensitive by default; use LOWER() or ILIKE for case-insensitive matching. SQLite is case-sensitive for = on text but case-insensitive for ASCII characters under LIKE. SQL Server depends on the database’s collation setting. Always check before relying on either behaviour.
Patterns inside strings are matched with the LIKE operator:
SELECT * FROM employees WHERE first_name LIKE 'Mo%';% matches any sequence of characters; _ matches exactly one character. So %mo matches names ending in mo, mo% matches names starting with mo, and %mo% matches names containing mo anywhere.
Beyond WHERE, real queries use other clauses:
JOINcombines multiple tables on matching columns. The combining logic is what makes a relational database worth using.GROUP BYaggregates rows that share a value in some column, so we can compute counts, sums, averages per group.HAVINGfilters the aggregated groups, the wayWHEREfilters individual rows.ORDER BYsorts the result.LIMITreturns only the first rows.
Interactive querying is iterative: start with a broad SELECT *, narrow with WHERE, project the columns we actually need, aggregate or join as the question demands. SQL is a declarative language. We describe what rows we want, not how to find them, and the database engine plans the actual access strategy.