SQLiteData advanced patterns, @Selection column groups, single-table inheritance, recursive CTEs, database views, custom aggregates, TableAlias self-joins, JSON/string aggregation
View on GitHubSelect agents to install to:
npx add-skill https://github.com/CharlesWiltgen/Axiom/blob/main/.claude-plugin/plugins/axiom/skills/axiom-sqlitedata-ref/SKILL.md -a claude-code --skill axiom-sqlitedata-refInstallation paths:
.claude/skills/axiom-sqlitedata-ref/# SQLiteData Advanced Reference
## Overview
Advanced query patterns and schema composition techniques for [SQLiteData](https://github.com/pointfreeco/sqlite-data) by Point-Free. Built on [GRDB](https://github.com/groue/GRDB.swift) and [StructuredQueries](https://github.com/pointfreeco/swift-structured-queries).
**For core patterns** (CRUD, CloudKit setup, @Table basics), see the `axiom-sqlitedata` discipline skill.
**This reference covers** advanced querying, schema composition, views, and custom aggregates.
**Requires** iOS 17+, Swift 6 strict concurrency
**Framework** SQLiteData 1.4+
---
## Column Groups and Schema Composition
SQLiteData provides powerful tools for composing schema types, enabling reuse, better organization, and single-table inheritance patterns.
### Column Groups
Group related columns into reusable types with `@Selection`:
```swift
// Define a reusable column group
@Selection
struct Timestamps {
let createdAt: Date
let updatedAt: Date?
}
// Use in multiple tables
@Table
nonisolated struct RemindersList: Identifiable {
let id: UUID
var title = ""
let timestamps: Timestamps // Embedded column group
}
@Table
nonisolated struct Reminder: Identifiable {
let id: UUID
var title = ""
var isCompleted = false
let timestamps: Timestamps // Same group, reused
}
```
**Important:** SQLite has no concept of grouped columns. Flatten all groupings in your CREATE TABLE:
```sql
CREATE TABLE "remindersLists" (
"id" TEXT PRIMARY KEY NOT NULL DEFAULT (uuid()),
"title" TEXT NOT NULL DEFAULT '',
"createdAt" TEXT NOT NULL,
"updatedAt" TEXT
) STRICT
```
#### Querying Column Groups
Access fields inside groups with dot syntax:
```swift
// Query a field inside the group
RemindersList
.where { $0.timestamps.createdAt <= cutoffDate }
.fetchAll(db)
// Compare entire group (flattens to tuple in SQL)
RemindersList
.where {
$0.timestamps <= Timestamps(createdAt: date1, updatedAt: date2)