65+ SQL commands and patterns with real examples. Search by keyword or filter by category — click any card to copy the example query.
Showing 73 of 73 commands — click any card to copy the example SQL
SQL JOINs Explained
JOINs are the backbone of relational SQL. INNER JOIN is the most common — it returns only rows where the condition matches in both tables, filtering out any unmatched records. LEFT JOIN (or LEFT OUTER JOIN) keeps every row from the left table and fills NULLs on the right where there is no match, which is ideal for finding users with no orders, or products never sold.
FULL OUTER JOIN returns all rows from both tables with NULLs on either side where there is no match. It is useful for reconciliation queries — finding rows present in one table but not the other. CROSS JOIN produces a Cartesian product and is rarely needed in practice, but it is handy for generating combinations (e.g., all size × color variants of a product). Self-JOINs — joining a table to itself — are essential for hierarchical data like employee-manager relationships or category trees.
Window Functions vs Aggregate Functions
Aggregate functions like SUM(), COUNT(), and AVG() collapse many rows into one summary row per group. Window functions use an OVER() clause to compute the same aggregates but keep every row in the output. This makes them indispensable for running totals, moving averages, and period-over-period comparisons without losing row-level detail.
ROW_NUMBER(), RANK(), and DENSE_RANK() assign ordinal positions within a partition — ROW_NUMBER() is strictly sequential with no ties; RANK() leaves gaps after ties (1, 1, 3); DENSE_RANK() does not (1, 1, 2). Use LAG() and LEAD() to access adjacent rows without a self-join, and NTILE(n) to bucket rows into quartiles or percentiles.
Query Optimization Tips
Start every optimization with EXPLAIN ANALYZE to understand the actual query plan and timings. Look for sequential scans on large tables — these usually benefit from an index on the filtered or joined column. Prefer partial indexes (with a WHERE clause) when only a subset of rows is queried frequently; they are smaller and faster to maintain.
Avoid SELECT * in production — fetch only the columns you need to reduce I/O and network transfer. Use EXISTS instead of IN with large subquery result sets, as EXISTS short-circuits on the first match. For pagination, keyset pagination (WHERE id > last_seen_id LIMIT n) scales far better than OFFSET-based pagination on large datasets, since OFFSET forces the database to scan and discard all preceding rows.
Frequently Asked Questions
What is the difference between INNER JOIN and LEFT JOIN?
INNER JOIN returns only rows where the join condition matches in both tables — if a user has no orders, they are excluded from the result. LEFT JOIN returns all rows from the left table regardless, filling columns from the right table with NULL where there is no match. Use LEFT JOIN when you want to keep all records from one side even if there are no related records on the other side.
What are window functions, and how are they different from GROUP BY?
GROUP BY collapses multiple rows into a single summary row per group, which means you lose the individual row data. Window functions (OVER clause) compute a value across a set of rows related to the current row but keep every row intact in the result set. This makes window functions ideal for running totals, rankings, and period-over-period comparisons where you still need the original row detail alongside the aggregate.
When should I use a CTE (WITH clause) instead of a subquery?
CTEs improve readability by naming intermediate result sets at the top of a query, making complex logic much easier to follow and debug. Use a CTE when you reference the same subquery more than once, when building recursive queries (hierarchies, trees), or simply when nesting would make the query hard to read. In most modern databases, CTEs and derived table subqueries have equivalent performance, though some optimizers may handle them differently.
When should I add a database index?
Add an index on columns that appear frequently in WHERE conditions, JOIN ON clauses, or ORDER BY clauses on large tables. Primary keys and UNIQUE columns are indexed automatically. Avoid over-indexing — each index slows down INSERT, UPDATE, and DELETE operations because the index must be updated too. Use EXPLAIN ANALYZE to confirm a query is performing a sequential scan on a large table before adding an index, and consider partial indexes for columns with many NULL values.
What is the difference between SQL and NoSQL databases?
SQL (relational) databases like PostgreSQL and MySQL store data in structured tables with a defined schema and use SQL to query it. They excel at complex queries, joins, transactions, and enforcing data integrity with foreign keys and constraints. NoSQL databases like MongoDB, DynamoDB, and Redis store data in flexible formats (documents, key-value pairs, graphs) and scale horizontally more easily. Choose SQL when your data is relational and consistency is critical; choose NoSQL when you need extreme write throughput, flexible schemas, or massive horizontal scale.