Pivoting and dynamic patterns
Pivoting turns category values into output columns. It changes presentation without removing the need for a defined grouping grain.
Conditional aggregation
SUM(CASE WHEN status='paid' THEN sales ELSE 0 END) AS paid_sales creates one measure column. Add a cancelled_sales expression to make another. This pattern is portable and explicit.
Native pivot forms
SQL Server supports PIVOT; PostgreSQL has extensions such as tablefunc for crosstab-style output. SQLite has no built-in PIVOT statement, so the runnable example uses conditional aggregation.
Dynamic categories
A fixed pivot knows its column names before execution. Dynamic columns require generating a statement in an application or supported database routine. Validate identifiers using an allowlist; parameters normally bind values, not column names.
Keep the contract stable
A report with new columns appearing every week can be hard to maintain. Consider returning a long-format category/value table and pivoting in the reporting layer instead.