Recommended Free Tools
This SQL cheat sheet puts the practical syntax for PostgreSQL, MySQL 8.4, SQLite and SQL Server in one reference. Start with the portable query shape, then use the labeled dialect variants for pagination, dates, strings, null handling, upserts and identifier quoting.
SQL query structure at a glance
A query normally reads from a source, filters rows, groups and aggregates, projects columns, sorts the result and limits the returned page. Use this skeleton as your starting point:
SELECT [DISTINCT] column_or_expression AS alias
FROM table_or_view AS t
[JOIN other_table AS o ON o.key = t.key]
[WHERE row_condition]
[GROUP BY grouping_columns]
[HAVING group_condition]
[ORDER BY sort_expression [ASC|DESC]]
[LIMIT/OFFSET or dialect equivalent];
The brackets indicate optional clauses, not literal characters. A select-list expression can be a column, calculation, conditional expression or aggregate.
Logical processing order
Use FROM/JOIN → WHERE → GROUP BY/HAVING → SELECT → DISTINCT → ORDER BY → LIMIT/OFFSET as a teaching model. It explains why a select-list alias usually cannot be referenced in WHERE: filtering logically occurs first. Optimizers can execute the physical operations in a different order while preserving the result.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
SELECT, aliases and expressions
Choose columns explicitly
SELECT
u.id,
u.email,
u.created_at AS signup_time
FROM users AS u;
Prefer explicit columns in application code. SELECT * is useful for exploration but couples a result to every future schema change. DISTINCT removes duplicate result rows after projection; it does not repair an incorrect join.
Conditional values
SELECT
order_id,
CASE
WHEN amount >= 1000 THEN 'large'
WHEN amount >= 100 THEN 'medium'
ELSE 'small'
END AS order_size
FROM orders;
COALESCE(value, fallback) returns the first non-NULL argument. Use it to present a default, but do not confuse presentation with data cleanup.
WHERE predicates and NULL
Basic predicates
SELECT *
FROM products
WHERE active = TRUE
AND (category = 'book' OR category = 'course')
AND price BETWEEN 20 AND 80;
- Use
IN ('paid', 'trial')for a finite set. - Use
LIKE 'Acme%'for a prefix pattern; wildcard and case-sensitivity rules vary by engine and collation. - Parenthesize mixed
AND/ORexpressions so precedence is unambiguous. - Use
IS NULLandIS NOT NULL, never= NULL. Comparisons with NULL produce an unknown truth value.
Dates and intervals
Date literal and interval syntax is dialect-specific. PostgreSQL example:
SELECT *
FROM orders
WHERE order_date >= DATE '2026-01-01'
AND order_date < DATE '2026-02-01';
For MySQL 8.4, a portable boundary can be written with quoted ISO values:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Rank #2
SELECT *
FROM orders
WHERE order_date >= '2026-01-01'
AND order_date < '2026-02-01';
Use a half-open range (inclusive start, exclusive end) for timestamps so adjacent monthly or daily windows do not overlap.
JOINs without accidental duplicates
INNER and LEFT JOIN
SELECT
c.customer_id,
c.name,
o.order_id,
o.amount
FROM customers AS c
LEFT JOIN orders AS o
ON o.customer_id = c.customer_id;
- INNER JOIN returns only rows with a match on both sides.
- LEFT JOIN preserves every left-side row; unmatched right-side columns are NULL.
- RIGHT JOIN and FULL OUTER JOIN are not equally available across engines. Check the SQLite version and your target dialect before using them.
Diagnose cardinality first
If one customer has five orders, the left join legitimately returns five rows for that customer. A many-to-many relationship can multiply rows dramatically. Check keys and relationship cardinality before adding DISTINCT; deduplication can hide a data-model or join-condition error.
GROUP BY, aggregates and HAVING
GROUP BY collapses input rows into groups for aggregate calculations. WHERE removes individual rows before grouping; HAVING removes groups after aggregation.
SELECT
customer_id,
COUNT(*) AS orders,
SUM(amount) AS revenue,
AVG(amount) AS average_order
FROM orders
WHERE order_date >= DATE '2026-01-01'
GROUP BY customer_id
HAVING SUM(amount) > 1000
ORDER BY revenue DESC;
COUNT(*)counts rows;COUNT(column)ignores NULL in that column.SUM,AVG,MINandMAXoperate per group.- Selected non-aggregated columns generally must appear in
GROUP BY. PostgreSQL documents a functional-dependency exception in some cases; do not assume every engine applies it the same way.
CTEs and set operators
Common table expressions
WITH recent_orders AS (
SELECT order_id, customer_id, amount
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '30 days'
)
SELECT customer_id, SUM(amount) AS recent_revenue
FROM recent_orders
GROUP BY customer_id;
The interval expression above is PostgreSQL-style. Rewrite date arithmetic for your engine (for example, MySQL 8.4 uses its own DATE_SUB forms). A CTE names an intermediate result, improving readability and allowing multiple references. Recursive CTE syntax is available in several engines but should be verified against the specific version and recursion limits.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Rank #3
Combine compatible result sets
SELECT email FROM newsletter_subscribers
UNION
SELECT email FROM customers;
SELECT email FROM newsletter_subscribers
UNION ALL
SELECT email FROM customers;
UNION removes duplicate rows; UNION ALL keeps them and is usually the right choice when the inputs are already disjoint or duplicates matter. INTERSECT returns rows present in both queries, and EXCEPT returns rows in the first but not the second. Each branch must expose the same number of compatible columns.
Window functions: keep detail while calculating across rows
Unlike GROUP BY, a window function calculates over related rows while retaining each detail row. The central pattern is function(...) OVER (PARTITION BY ... ORDER BY ...).
SELECT
customer_id,
order_date,
amount,
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY order_date DESC
) AS newest_rank,
SUM(amount) OVER (
PARTITION BY customer_id
ORDER BY order_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS running_total
FROM orders;
Common patterns
- Top N per group: put
ROW_NUMBER()orDENSE_RANK()in a CTE, then filter the rank in an outer query because window results are produced afterWHERE. - Running totals: specify an explicit frame such as
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW. - Previous/next comparison: use
LAG(value)andLEAD(value)with a deterministic order. - Percent or overall totals: use a second window without
PARTITION BY, such asSUM(amount) OVER ().
SQLite documents ROWS, RANGE and GROUPS frame types with boundaries and optional exclusion. Frame defaults differ in effect when peer rows share the same ordering value, so specify the frame when exact running behavior matters.
Pagination and ordering by dialect
| Engine | Typical pagination | Important notes |
|---|---|---|
| PostgreSQL | ORDER BY ... LIMIT 50 OFFSET 100 |
Supports explicit NULLS FIRST/NULLS LAST; use a stable unique tie-breaker in ORDER BY. |
| MySQL 8.4 | ORDER BY ... LIMIT 100 OFFSET 50 (also LIMIT 50, 100) |
Use the 8.4 SELECT grammar for MySQL-only modifiers. |
| SQLite | ORDER BY ... LIMIT 50 OFFSET 100 |
Check the SQLite version before assuming server-database features or broad ALTER TABLE support. |
| SQL Server | ORDER BY ... OFFSET 100 ROWS FETCH NEXT 50 ROWS ONLY |
ORDER BY is required with OFFSET; named WINDOW requires SQL Server 2022 (16.x) and compatibility level 160 or higher. |
Offset pagination gets slower at deep pages because the engine still walks skipped rows. For a changing, large dataset, keyset pagination is more stable:
Rank #4
SELECT order_id, order_date, amount
FROM orders
WHERE (order_date, order_id) < ('2026-09-01', 9000)
ORDER BY order_date DESC, order_id DESC
LIMIT 50;
The row-value comparison shown is common in PostgreSQL and MySQL; adapt it for engines that require expanded predicates.
Portable syntax versus dialect-specific features
Identifier quoting and strings
- Use unquoted, lowercase-style identifiers for maximum portability.
- Standard double quotes denote identifiers in PostgreSQL and SQLite; SQL Server commonly uses brackets such as
[Order], while MySQL commonly uses backticks such as`Order`(depending on SQL mode). - Single quotes are for string literals. Do not rely on a dialect accepting double-quoted strings.
- String concatenation differs: PostgreSQL and SQLite commonly use
||; MySQL commonly usesCONCAT(a, b); SQL Server commonly uses+orCONCAT. Label the dialect in shared snippets.
NULL ordering
PostgreSQL lets you write ORDER BY score DESC NULLS LAST. Other engines may place NULLs differently by default or require a boolean expression such as ORDER BY (score IS NULL), score DESC. Test the actual target engine rather than assuming a universal default.
Upsert and merge
There is no single portable upsert statement. PostgreSQL and SQLite support INSERT ... ON CONFLICT forms; MySQL uses INSERT ... ON DUPLICATE KEY UPDATE; SQL Server provides MERGE and other update-then-insert patterns. Review the vendor’s version-specific concurrency guidance before using these in production.
Debugging checklist
- Reduce the query to
SELECT ... FROM ..., then add joins one at a time. - Run the
WHEREpredicates independently and inspect NULL behavior. - Compare row counts before and after each join to expose cardinality explosions.
- Move aggregate filters from
WHEREtoHAVING; move row filters earlier when possible. - For a window query, verify the partition and add a deterministic tie-breaker to the ordering.
- Qualify every ambiguous column with its table alias.
- Use
EXPLAIN(or the engine’s analyze variant) to inspect scans, joins and estimated rows; avoid claiming a plan is faster without measuring on representative data.
Common errors and fixes
- “Column must appear in GROUP BY”: group the column, aggregate it, or move the calculation to a window expression.
- Unexpected duplicate rows: inspect one-to-many or many-to-many joins; do not immediately add
DISTINCT. - Empty result when checking missing values: replace
column = NULLwithcolumn IS NULL. - Unknown function or syntax: confirm engine and version, then replace the dialect-specific function with its labeled equivalent.
- Unstable pages: add a unique column to
ORDER BY; without a total order, ties can move between pages.
Archive this cheat sheet as a clean reference image
For a do-it-yourself capture, open the rendered article in a browser, wait for all code blocks and fonts to load, dismiss consent prompts, then use the browser’s Print command and choose “Save as PDF.” For a PNG or WebP, use the browser’s full-page screenshot tool or a scripted headless browser, set a viewport wide enough for tables, and verify that horizontally scrollable code is not clipped.
Best Value
Or skip the browser setup
ScreenshotNeo takes a screenshot or PDF with one GET request. It accepts the cookie/consent banner like a visitor, then removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the page verdict and billing status in X-Page-Verdict and X-Billed headers. An MCP server provides take_screenshot, get_page_info and capture_pdf tools to Claude, Cursor and other MCP clients.
See the ScreenshotNeo API documentation for all 63 options, including full-page lazy-image loading, CSS-selector element capture, dark mode, device presets, retina scale, PDF page ranges, custom CSS/JavaScript, click and wait actions, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, TTL caching, signed image links, asynchronous webhooks, 100-URL bulk calls, usage data and the OpenAPI specification.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://freedom251.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://freedom251.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://freedom251.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The Free plan includes 1,000 shots each month with no card. Starter is $5 for 3,000 shots, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000 and Business $249 for 1,000,000; yearly billing gives two months free, and every feature is included on every plan. Create a free ScreenshotNeo account to capture this reference without configuring a browser.
Frequently Asked Questions
Does SQL guarantee row order without ORDER BY?
No. A result has no guaranteed order unless the query includes ORDER BY. Even an execution plan that appears stable can change after statistics, indexes or engine versions change.
Free tools Windows power users keep installed
One-click scans. No signup required.
How can I check whether a query is portable?
Run a small test suite against each target engine and version, covering pagination, dates, NULL ordering, quoting, upserts and window frames. Keep dialect-specific statements in clearly labeled modules.
Should I use a CTE or a subquery?
Choose the form that makes the data flow easiest to verify, then inspect the execution plan on your engine. Readability and measured behavior matter more than a blanket rule.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




