SELECT is the cornerstone of SQL and the primary means of reading data. A SELECT statement creates a virtual table (the result set) by projecting columns, filtering rows, joining related tables, grouping aggregates, ordering results, and optionally limiting the number of rows returned. It never modifies data. Because most database optimizers focus heavily on SELECT, understanding its clauses helps you write performant queries. The logical processing order is FROM, WHERE, GROUP BY, HAVING, SELECT, DISTINCT, ORDER BY, LIMIT-OFFSET, though the written order differs. Some dialects add proprietary extensions such as TOP (SQL Server) or QUALIFY (Snowflake). You can nest SELECT inside subqueries and common table expressions (CTEs) to build complex analyses. Caveats: omitting a WHERE clause selects all rows, NULLs require special handling with IS NULL, and non-aggregated columns must appear in GROUP BY unless the dialect supports functional dependency shortcuts (e.g., MySQL ONLY_FULL_GROUP_BY disabled).
column_list
(list) - One or more columns or expressions to return.table_expression
(table/view/cte) - Source data set; may include JOINs or subqueries.WHERE condition
(boolean) - Row-level filter applied before grouping.GROUP BY column_list
(list) - Columns that define aggregation groups.HAVING condition
(boolean) - Filter applied after aggregation.ORDER BY column_list
(list) - Defines sort order of the result.LIMIT count
(integer) - Maximum number of rows to return (not in all dialects).OFFSET start
(integer) - Rows to skip before returning results.DISTINCT
(keyword) - Removes duplicate rows from the projection.ALL
(keyword) - Returns all rows, including duplicates (default).ANSI SQL-86 (X3.135-1986)
It returns a result set - a virtual table of rows and columns that match the query conditions.
Yes in some dialects. For example, `SELECT 1;` returns a single row with the value 1, useful for quick calculations or health checks.
DISTINCT removes duplicate rows across all selected columns, while GROUP BY collapses rows into groups so you can apply aggregate functions like COUNT or SUM.
Common causes include missing indexes on filtered or joined columns, returning too many rows, or sorting large result sets without supporting indexes.