software:mysql:withrecursive
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| software:mysql:withrecursive [2026/02/06 21:41] – created rodolico | software:mysql:withrecursive [2026/02/06 22:05] (current) – rodolico | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== The with recursive | + | ====== The WITH RECURSIVE |
| - | Using FrontAccounting (https:// | + | Using [[https:// |
| - | The basic query, after some looking around, turned out to be: | + | ===== Warnings ===== |
| + | |||
| + | Just like it says, this is recursion, generally used to retrieve data from a hierarchical configuration. | ||
| + | |||
| + | It is very resource intensive if it has to recurse very deep. Be careful when implementing this in the real world, as a poorly written CTE can blow up your database server. | ||
| + | |||
| + | ===== Original Task ===== | ||
| + | |||
| + | After some looking around, | ||
| <code sql> | <code sql> | ||
| Line 23: | Line 31: | ||
| </ | </ | ||
| - | I then ran the output of this through a Perl script | + | I then ran the output of this through a Perl script |
| - | I was able to bypass the Perl script by learning the new CTE (Common Table Expressions) syntax for MySQL (and MariaDB). This is similar to processing queries into temp tables, then running an additional query against them. | + | I was able to bypass the Perl script by learning the CTE (Common Table Expressions) syntax for MySQL (and MariaDB). This is similar to processing queries into temp tables, then running an additional query against them. |
| + | |||
| + | ===== Solution ===== | ||
| I'll say more about it later, but here is the resulting query. | I'll say more about it later, but here is the resulting query. | ||
| Line 61: | Line 71: | ||
| params AS ( | params AS ( | ||
| | | ||
| - | DATE_FORMAT(MIN(nextDue), | + | DATE_FORMAT(MIN(nextDue), |
| - | DATE_ADD(DATE_FORMAT(MIN(nextDue), | + | DATE_ADD(DATE_FORMAT(MIN(nextDue), |
| FROM recurrent | FROM recurrent | ||
| ), | ), | ||
| Line 77: | Line 87: | ||
| SUM( | SUM( | ||
| CASE | CASE | ||
| - | WHEN month_start >= DATE_FORMAT(nextDue, | + | WHEN month_start >= DATE_FORMAT(nextDue, |
| AND MOD( | AND MOD( | ||
| | | ||
| Line 92: | Line 102: | ||
| </ | </ | ||
| + | |||
| + | * This projects 12 months into the future. Since our recurrent invoices have that as a maximum (annual), it works for us. If you want 6 or 24 months, change the constant 12 near the middle of the query: //INTERVAL 12 MONTH//. | ||
| + | * Our invoicing is done on the 15th of every month, so in three locations we hard-code the date format. Look for //' | ||
| + | |||
| + | ===== Explanation ===== | ||
| + | |||
| + | |||
| + | ==== Purpose ==== | ||
| + | The query aggregates recurring invoice totals by month. Each invoice recurs every '' | ||
| + | |||
| + | ==== Query Structure ==== | ||
| + | The query uses three CTEs: | ||
| + | |||
| + | 1. **'' | ||
| + | * Builds a normalized recurring-invoice dataset from FrontAccounting tables. | ||
| + | * Computes: | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | 2. **'' | ||
| + | * Calculates the reporting window: | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | 3. **'' | ||
| + | * Generates a row per calendar month from '' | ||
| + | |||
| + | ==== Final Aggregation ==== | ||
| + | For each generated '' | ||
| + | |||
| + | * A row is billed when the difference in months between '' | ||
| + | * This is evaluated with: | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | ==== Output ==== | ||
| + | The result returns one row per month: | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | ==== Adjusting the Reporting Range ==== | ||
| + | To change the number of months produced, edit the interval in the '' | ||
| + | |||
| + | <code sql> | ||
| + | DATE_ADD(DATE_FORMAT(MIN(nextDue), | ||
| + | </ | ||
| + | |||
| + | For example, replace '' | ||
| + | |||
| + | ==== Notes ==== | ||
| + | * The query is compatible with MariaDB 10.11. | ||
| + | * If there are no '' | ||
| + | |||
software/mysql/withrecursive.1770435673.txt.gz · Last modified: by rodolico
