Querying Data with SELECT

1. Selecting All Columns

SELECT * FROM customers;
AvoidWhy
SELECT *Schema drift, sends unneeded bytes, blocks index-only scans

2. Selecting Specific Columns

SELECT id, email, full_name FROM customers WHERE status = 'active';

3. Using Column Aliases

SELECT id AS customer_id, full_name AS name FROM customers;
FormNotes
AS keywordOptional but clearer
Quoted aliasSELECT id AS "Customer ID" preserves case/space

4. Using Expression Aliases

SELECT total_cents/100.0 AS total_dollars,
       upper(email) AS email_uc
  FROM orders;

5. Selecting Distinct Values

SELECT DISTINCT status FROM orders;
SELECT DISTINCT status, customer_id FROM orders;

6. Using DISTINCT ON

-- Latest order per customer
SELECT DISTINCT ON (customer_id) *
  FROM orders
 ORDER BY customer_id, placed_at DESC;
RuleDetail
ORDER BY requiredFirst column must match DISTINCT ON list
ReturnsFirst row of each group per ORDER BY

7. Limiting Results

SELECT * FROM orders ORDER BY placed_at DESC LIMIT 10;

8. Offsetting Results

SELECT * FROM orders ORDER BY id OFFSET 20 LIMIT 10;
Warning: Large OFFSET is O(N) scan; use keyset pagination WHERE id > :last_id ORDER BY id LIMIT n.

9. Combining LIMIT and OFFSET

ApproachWhen
OFFSET/LIMITSmall datasets, admin UIs
Keyset (cursor)Infinite scroll, large tables
DECLARE CURSORServer-side cursor, low-memory paging

10. Using FETCH FIRST

SELECT * FROM orders ORDER BY placed_at DESC
 FETCH FIRST 10 ROWS ONLY;
SELECT * FROM orders ORDER BY total_cents DESC
 FETCH FIRST 5 ROWS WITH TIES;
ClauseBehavior
ROWS ONLYStrict N rows
WITH TIESIncludes peers per ORDER BY PG 13+