|
| 1 | +--- |
| 2 | +title: R2 SQL now supports aggregations and schema discovery |
| 3 | +description: Perform aggregations, grouping, and filtering on Apache Iceberg tables stored in R2 Data Catalog |
| 4 | +date: 2025-12-12 |
| 5 | +products: |
| 6 | + - r2-sql |
| 7 | +hidden: false |
| 8 | +--- |
| 9 | + |
| 10 | +R2 SQL now supports aggregation functions, `GROUP BY`, `HAVING`, along with schema discovery commands to make it easy to explore your data catalog. |
| 11 | + |
| 12 | +## Aggregation Functions |
| 13 | + |
| 14 | +You can now perform aggregations on Apache Iceberg tables in [R2 Data Catalog](/r2/data-catalog/) using standard SQL functions including `COUNT(*)`, `SUM()`, `AVG()`, `MIN()`, and `MAX()`. Combine these with `GROUP BY` to analyze data across dimensions, and use `HAVING` to filter aggregated results. |
| 15 | + |
| 16 | +```sql |
| 17 | +-- Calculate average transaction amounts by department |
| 18 | +SELECT department, COUNT(*), AVG(total_amount) |
| 19 | +FROM my_namespace.sales_data |
| 20 | +WHERE region = 'North' |
| 21 | +GROUP BY department |
| 22 | +HAVING COUNT(*) > 50 |
| 23 | +ORDER BY AVG(total_amount) DESC |
| 24 | +``` |
| 25 | + |
| 26 | +```sql |
| 27 | +-- Find high-value departments |
| 28 | +SELECT department, SUM(total_amount) |
| 29 | +FROM my_namespace.sales_data |
| 30 | +GROUP BY department |
| 31 | +HAVING SUM(total_amount) > 50000 |
| 32 | +``` |
| 33 | + |
| 34 | +## Schema Discovery |
| 35 | + |
| 36 | +New metadata commands make it easy to explore your data catalog and understand table structures: |
| 37 | + |
| 38 | +- `SHOW DATABASES` or `SHOW NAMESPACES` - List all available namespaces |
| 39 | +- `SHOW TABLES IN namespace_name` - List tables within a namespace |
| 40 | +- `DESCRIBE namespace_name.table_name` - View table schema and column types |
| 41 | + |
| 42 | +```bash |
| 43 | +❯ npx wrangler r2 sql query "{ACCOUNT_ID}_{BUCKET_NAME}" "DESCRIBE default.sales_data;" |
| 44 | + |
| 45 | + ⛅️ wrangler 4.54.0 |
| 46 | +───────────────────────────────────────────── |
| 47 | + |
| 48 | +┌──────────────────┬────────────────┬──────────┬─────────────────┬───────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────┐ |
| 49 | +│ column_name │ type │ required │ initial_default │ write_default │ doc │ |
| 50 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 51 | +│ sale_id │ BIGINT │ false │ │ │ Unique identifier for each sales transaction │ |
| 52 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 53 | +│ sale_timestamp │ TIMESTAMPTZ │ false │ │ │ Exact date and time when the sale occurred (used for partitioning) │ |
| 54 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 55 | +│ department │ TEXT │ false │ │ │ Product department (8 categories: Electronics, Beauty, Home, Toys, Sports, Food, Clothing, Books) │ |
| 56 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 57 | +│ category │ TEXT │ false │ │ │ Product category grouping (4 categories: Premium, Standard, Budget, Clearance) │ |
| 58 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 59 | +│ region │ TEXT │ false │ │ │ Geographic sales region (5 regions: North, South, East, West, Central) │ |
| 60 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 61 | +│ product_id │ INT │ false │ │ │ Unique identifier for the product sold │ |
| 62 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 63 | +│ quantity │ INT │ false │ │ │ Number of units sold in this transaction (range: 1-50) │ |
| 64 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 65 | +│ unit_price │ DECIMAL(10, 2) │ false │ │ │ Price per unit in dollars (range: $5.00-$500.00) │ |
| 66 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 67 | +│ total_amount │ DECIMAL(10, 2) │ false │ │ │ Total sale amount before tax (quantity × unit_price with discounts applied) │ |
| 68 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 69 | +│ discount_percent │ INT │ false │ │ │ Discount percentage applied to this sale (0-50%) │ |
| 70 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 71 | +│ tax_amount │ DECIMAL(10, 2) │ false │ │ │ Tax amount collected on this sale │ |
| 72 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 73 | +│ profit_margin │ DECIMAL(10, 2) │ false │ │ │ Profit margin on this sale as a decimal percentage │ |
| 74 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 75 | +│ customer_id │ INT │ false │ │ │ Unique identifier for the customer who made the purchase │ |
| 76 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 77 | +│ is_online_sale │ BOOLEAN │ false │ │ │ Boolean flag indicating if sale was made online (true) or in-store (false) │ |
| 78 | +├──────────────────┼────────────────┼──────────┼─────────────────┼───────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 79 | +│ sale_date │ DATE │ false │ │ │ Calendar date of the sale (extracted from sale_timestamp) │ |
| 80 | +└──────────────────┴────────────────┴──────────┴─────────────────┴───────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────┘ |
| 81 | +Read 0 B across 0 files from R2 |
| 82 | +On average, 0 B / s |
| 83 | + |
| 84 | +``` |
| 85 | +
|
| 86 | +To learn more about the new aggregation capabilities and schema discovery commands, check out the [SQL reference](/r2-sql/sql-reference/). If you're new to R2 SQL, visit our [getting started guide](/r2-sql/get-started/) to begin querying your data. |
0 commit comments