The SELECT statement retrieves rows and columns from one or more PostgreSQL tables, optionally filtering, grouping, and ordering the result.
SELECT returns a result-set built from specified columns, rows, and expressions. It can pull data from one or many tables, filter with WHERE, summarise with GROUP BY, sort with ORDER BY, and trim output with LIMIT / OFFSET. It is the workhorse of every read query.
Use a wildcard: SELECT * FROM Customers;
. This grabs all columns for every customer. In production queries, list needed columns explicitly to avoid unnecessary network transfer and surprise schema changes.
List them: SELECT id, name, email FROM Customers;
. Aliases (e.g., name AS customer_name
) improve readability and allow duplicate column names in joins.
Use WHERE: SELECT * FROM Orders WHERE total_amount > 100;
. Combine filters with AND/OR, compare dates with order_date >= '2024-01-01'
, and check membership via IN
or NOT IN
.
JOIN merges related rows. Example: SELECT c.name, o.order_date FROM Customers c JOIN Orders o ON o.customer_id = c.id;
. Prefer explicit JOIN syntax for clarity and performance planning.
Combine aggregate functions with GROUP BY. Example: SELECT customer_id, SUM(total_amount) AS lifetime_value FROM Orders GROUP BY customer_id HAVING SUM(total_amount) > 500;
.
ORDER BY sorts results. LIMIT and OFFSET paginate: SELECT * FROM Products ORDER BY price DESC LIMIT 10 OFFSET 20;
. Add indexes on sort columns for faster response times.
Yes. SELECT 1 AS one;
is valid and often used for quick calculations or health checks.
Add DISTINCT: SELECT DISTINCT customer_id FROM Orders;
. Be aware that DISTINCT incurs extra sorting or hashing.
Common reasons: missing indexes on join or filter columns, SELECT *, large text columns, or no LIMIT in UI queries. Use EXPLAIN to diagnose.