@bonnard/cli 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/bon.mjs +1838 -100
- package/dist/bin/models-IsV2sX74.mjs +76 -0
- package/dist/bin/{validate-Bd1D39Bj.mjs → validate-C4EHvJzJ.mjs} +47 -4
- package/dist/docs/README.md +82 -0
- package/dist/docs/_index.md +69 -0
- package/dist/docs/topics/cubes.data-source.md +96 -0
- package/dist/docs/topics/cubes.dimensions.format.md +199 -0
- package/dist/docs/topics/cubes.dimensions.md +188 -0
- package/dist/docs/topics/cubes.dimensions.primary-key.md +110 -0
- package/dist/docs/topics/cubes.dimensions.sub-query.md +178 -0
- package/dist/docs/topics/cubes.dimensions.time.md +115 -0
- package/dist/docs/topics/cubes.dimensions.types.md +111 -0
- package/dist/docs/topics/cubes.extends.md +153 -0
- package/dist/docs/topics/cubes.hierarchies.md +178 -0
- package/dist/docs/topics/cubes.joins.md +119 -0
- package/dist/docs/topics/cubes.md +121 -0
- package/dist/docs/topics/cubes.measures.calculated.md +103 -0
- package/dist/docs/topics/cubes.measures.drill-members.md +162 -0
- package/dist/docs/topics/cubes.measures.filters.md +90 -0
- package/dist/docs/topics/cubes.measures.format.md +157 -0
- package/dist/docs/topics/cubes.measures.md +166 -0
- package/dist/docs/topics/cubes.measures.rolling.md +123 -0
- package/dist/docs/topics/cubes.measures.types.md +126 -0
- package/dist/docs/topics/cubes.public.md +176 -0
- package/dist/docs/topics/cubes.refresh-key.md +157 -0
- package/dist/docs/topics/cubes.segments.md +125 -0
- package/dist/docs/topics/cubes.sql.md +65 -0
- package/dist/docs/topics/pre-aggregations.md +130 -0
- package/dist/docs/topics/pre-aggregations.rollup.md +166 -0
- package/dist/docs/topics/syntax.context-variables.md +157 -0
- package/dist/docs/topics/syntax.md +137 -0
- package/dist/docs/topics/syntax.references.md +178 -0
- package/dist/docs/topics/views.cubes.md +166 -0
- package/dist/docs/topics/views.folders.md +158 -0
- package/dist/docs/topics/views.includes.md +143 -0
- package/dist/docs/topics/views.md +142 -0
- package/dist/docs/topics/workflow.deploy.md +132 -0
- package/dist/docs/topics/workflow.md +151 -0
- package/dist/docs/topics/workflow.query.md +203 -0
- package/dist/docs/topics/workflow.validate.md +156 -0
- package/dist/templates/claude/rules/bonnard.md +15 -0
- package/dist/templates/claude/settings.json +7 -0
- package/dist/templates/claude/skills/bonnard-cli/SKILL.md +59 -0
- package/dist/templates/claude/skills/bonnard-queries/SKILL.md +68 -0
- package/dist/templates/cursor/rules/bonnard-cli.mdc +47 -0
- package/dist/templates/cursor/rules/bonnard-queries.mdc +49 -0
- package/dist/templates/cursor/rules/bonnard.mdc +20 -0
- package/dist/templates/shared/bonnard.md +81 -0
- package/package.json +13 -8
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# cubes.measures.types
|
|
2
|
+
|
|
3
|
+
> The 12 measure types available for aggregating data.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Cube supports 12 measure types that determine how values are aggregated. Choose the right type based on your analytical needs.
|
|
8
|
+
|
|
9
|
+
## Measure Types
|
|
10
|
+
|
|
11
|
+
### count
|
|
12
|
+
Counts the number of rows.
|
|
13
|
+
|
|
14
|
+
```yaml
|
|
15
|
+
- name: count
|
|
16
|
+
type: count
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### count_distinct
|
|
20
|
+
Counts unique values of a column.
|
|
21
|
+
|
|
22
|
+
```yaml
|
|
23
|
+
- name: unique_users
|
|
24
|
+
type: count_distinct
|
|
25
|
+
sql: user_id
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### count_distinct_approx
|
|
29
|
+
Approximate count distinct (faster for large datasets).
|
|
30
|
+
|
|
31
|
+
```yaml
|
|
32
|
+
- name: approx_unique_users
|
|
33
|
+
type: count_distinct_approx
|
|
34
|
+
sql: user_id
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### sum
|
|
38
|
+
Adds up numeric values.
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
- name: total_revenue
|
|
42
|
+
type: sum
|
|
43
|
+
sql: amount
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### avg
|
|
47
|
+
Calculates the average of numeric values.
|
|
48
|
+
|
|
49
|
+
```yaml
|
|
50
|
+
- name: average_order_value
|
|
51
|
+
type: avg
|
|
52
|
+
sql: amount
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### min
|
|
56
|
+
Returns the minimum value.
|
|
57
|
+
|
|
58
|
+
```yaml
|
|
59
|
+
- name: first_order_date
|
|
60
|
+
type: min
|
|
61
|
+
sql: created_at
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### max
|
|
65
|
+
Returns the maximum value.
|
|
66
|
+
|
|
67
|
+
```yaml
|
|
68
|
+
- name: last_order_date
|
|
69
|
+
type: max
|
|
70
|
+
sql: created_at
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### number
|
|
74
|
+
A calculated number (not aggregated from rows).
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
- name: conversion_rate
|
|
78
|
+
type: number
|
|
79
|
+
sql: "{completed_orders} / NULLIF({total_orders}, 0)"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### string
|
|
83
|
+
A calculated string value.
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
- name: status_label
|
|
87
|
+
type: string
|
|
88
|
+
sql: "'Active'"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### time
|
|
92
|
+
A calculated time value.
|
|
93
|
+
|
|
94
|
+
```yaml
|
|
95
|
+
- name: current_timestamp
|
|
96
|
+
type: time
|
|
97
|
+
sql: NOW()
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### boolean
|
|
101
|
+
A calculated boolean value.
|
|
102
|
+
|
|
103
|
+
```yaml
|
|
104
|
+
- name: has_orders
|
|
105
|
+
type: boolean
|
|
106
|
+
sql: "{count} > 0"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### number_agg
|
|
110
|
+
Custom aggregate function (advanced).
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
- name: median_price
|
|
114
|
+
type: number_agg
|
|
115
|
+
sql: "PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY {CUBE}.price)"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## See Also
|
|
119
|
+
|
|
120
|
+
- cubes.measures
|
|
121
|
+
- cubes.measures.calculated
|
|
122
|
+
- cubes.measures.filters
|
|
123
|
+
|
|
124
|
+
## More Information
|
|
125
|
+
|
|
126
|
+
https://cube.dev/docs/reference/data-model/types-and-formats#measure-types
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# cubes.public
|
|
2
|
+
|
|
3
|
+
> Control visibility of cubes, measures, and dimensions in the API.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `public` property controls whether a cube or its members are exposed through the API. Set to `false` to hide internal or intermediate data from consumers.
|
|
8
|
+
|
|
9
|
+
## Example
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
cubes:
|
|
13
|
+
# Hidden cube - used for joins only
|
|
14
|
+
- name: internal_mappings
|
|
15
|
+
public: false
|
|
16
|
+
sql_table: internal.mappings
|
|
17
|
+
|
|
18
|
+
dimensions:
|
|
19
|
+
- name: id
|
|
20
|
+
type: number
|
|
21
|
+
sql: id
|
|
22
|
+
primary_key: true
|
|
23
|
+
|
|
24
|
+
# Public cube with some hidden members
|
|
25
|
+
- name: orders
|
|
26
|
+
sql_table: orders
|
|
27
|
+
|
|
28
|
+
measures:
|
|
29
|
+
- name: count
|
|
30
|
+
type: count
|
|
31
|
+
|
|
32
|
+
- name: internal_score
|
|
33
|
+
type: avg
|
|
34
|
+
sql: score
|
|
35
|
+
public: false # Hidden from API
|
|
36
|
+
|
|
37
|
+
dimensions:
|
|
38
|
+
- name: id
|
|
39
|
+
type: number
|
|
40
|
+
sql: id
|
|
41
|
+
primary_key: true
|
|
42
|
+
public: false # Primary keys auto-hide by default
|
|
43
|
+
|
|
44
|
+
- name: status
|
|
45
|
+
type: string
|
|
46
|
+
sql: status
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Syntax
|
|
50
|
+
|
|
51
|
+
### Cube Level
|
|
52
|
+
|
|
53
|
+
```yaml
|
|
54
|
+
cubes:
|
|
55
|
+
- name: internal_cube
|
|
56
|
+
public: false
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Measure Level
|
|
60
|
+
|
|
61
|
+
```yaml
|
|
62
|
+
measures:
|
|
63
|
+
- name: debug_metric
|
|
64
|
+
type: count
|
|
65
|
+
public: false
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Dimension Level
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
dimensions:
|
|
72
|
+
- name: internal_id
|
|
73
|
+
type: string
|
|
74
|
+
sql: internal_id
|
|
75
|
+
public: false
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Segment Level
|
|
79
|
+
|
|
80
|
+
```yaml
|
|
81
|
+
segments:
|
|
82
|
+
- name: test_users
|
|
83
|
+
sql: "{CUBE}.is_test = true"
|
|
84
|
+
public: false
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Default Behavior
|
|
88
|
+
|
|
89
|
+
| Member Type | Default `public` |
|
|
90
|
+
|-------------|------------------|
|
|
91
|
+
| Cube | `true` |
|
|
92
|
+
| Measure | `true` |
|
|
93
|
+
| Dimension | `true` |
|
|
94
|
+
| Dimension with `primary_key: true` | `false` |
|
|
95
|
+
| Segment | `true` |
|
|
96
|
+
|
|
97
|
+
## Use Cases
|
|
98
|
+
|
|
99
|
+
### Internal Cubes
|
|
100
|
+
|
|
101
|
+
Hide cubes used only for joins or intermediate calculations:
|
|
102
|
+
|
|
103
|
+
```yaml
|
|
104
|
+
cubes:
|
|
105
|
+
- name: user_scores_internal
|
|
106
|
+
public: false
|
|
107
|
+
sql: "SELECT user_id, calculate_score() as score FROM users"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Sensitive Fields
|
|
111
|
+
|
|
112
|
+
Hide fields that shouldn't be queried directly:
|
|
113
|
+
|
|
114
|
+
```yaml
|
|
115
|
+
dimensions:
|
|
116
|
+
- name: password_hash
|
|
117
|
+
type: string
|
|
118
|
+
sql: password_hash
|
|
119
|
+
public: false
|
|
120
|
+
|
|
121
|
+
- name: api_secret
|
|
122
|
+
type: string
|
|
123
|
+
sql: api_secret
|
|
124
|
+
public: false
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Intermediate Measures
|
|
128
|
+
|
|
129
|
+
Hide measures used only in calculations:
|
|
130
|
+
|
|
131
|
+
```yaml
|
|
132
|
+
measures:
|
|
133
|
+
- name: raw_numerator
|
|
134
|
+
type: sum
|
|
135
|
+
sql: value
|
|
136
|
+
public: false
|
|
137
|
+
|
|
138
|
+
- name: raw_denominator
|
|
139
|
+
type: count
|
|
140
|
+
public: false
|
|
141
|
+
|
|
142
|
+
- name: ratio
|
|
143
|
+
type: number
|
|
144
|
+
sql: "{raw_numerator} / NULLIF({raw_denominator}, 0)"
|
|
145
|
+
# This is public (default)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Debug/Test Members
|
|
149
|
+
|
|
150
|
+
```yaml
|
|
151
|
+
segments:
|
|
152
|
+
- name: test_data
|
|
153
|
+
sql: "{CUBE}.is_test = true"
|
|
154
|
+
public: false
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Dynamic Visibility
|
|
158
|
+
|
|
159
|
+
Use `COMPILE_CONTEXT` for dynamic visibility based on context:
|
|
160
|
+
|
|
161
|
+
```yaml
|
|
162
|
+
cubes:
|
|
163
|
+
- name: admin_metrics
|
|
164
|
+
public: "{{ 'true' if COMPILE_CONTEXT.role == 'admin' else 'false' }}"
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## See Also
|
|
168
|
+
|
|
169
|
+
- cubes
|
|
170
|
+
- cubes.measures
|
|
171
|
+
- cubes.dimensions
|
|
172
|
+
- views
|
|
173
|
+
|
|
174
|
+
## More Information
|
|
175
|
+
|
|
176
|
+
https://cube.dev/docs/reference/data-model/cube#public
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# cubes.refresh-key
|
|
2
|
+
|
|
3
|
+
> Control when cube data is refreshed in the cache.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `refresh_key` property determines when Cube's cache should be invalidated. Use it to ensure queries return fresh data while optimizing performance.
|
|
8
|
+
|
|
9
|
+
## Example
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
cubes:
|
|
13
|
+
- name: orders
|
|
14
|
+
sql_table: orders
|
|
15
|
+
|
|
16
|
+
refresh_key:
|
|
17
|
+
every: 1 hour
|
|
18
|
+
|
|
19
|
+
measures:
|
|
20
|
+
- name: count
|
|
21
|
+
type: count
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Refresh Strategies
|
|
25
|
+
|
|
26
|
+
### Time-Based Refresh
|
|
27
|
+
|
|
28
|
+
Refresh at regular intervals:
|
|
29
|
+
|
|
30
|
+
```yaml
|
|
31
|
+
refresh_key:
|
|
32
|
+
every: 1 hour
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
refresh_key:
|
|
37
|
+
every: 10 minute
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
refresh_key:
|
|
42
|
+
every: 1 day
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### SQL-Based Refresh
|
|
46
|
+
|
|
47
|
+
Refresh when a SQL query returns a different value:
|
|
48
|
+
|
|
49
|
+
```yaml
|
|
50
|
+
refresh_key:
|
|
51
|
+
sql: SELECT MAX(updated_at) FROM orders
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This is efficient for append-only or update-tracked tables.
|
|
55
|
+
|
|
56
|
+
### Combined Approach
|
|
57
|
+
|
|
58
|
+
Use SQL with a time-based check interval:
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
refresh_key:
|
|
62
|
+
sql: SELECT MAX(updated_at) FROM orders
|
|
63
|
+
every: 5 minute
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The SQL runs every 5 minutes; cache refreshes only when the result changes.
|
|
67
|
+
|
|
68
|
+
## Syntax
|
|
69
|
+
|
|
70
|
+
### every
|
|
71
|
+
|
|
72
|
+
Time interval format: `<number> <unit>`
|
|
73
|
+
|
|
74
|
+
| Unit | Examples |
|
|
75
|
+
|------|----------|
|
|
76
|
+
| `second` | `30 second` |
|
|
77
|
+
| `minute` | `5 minute`, `10 minute` |
|
|
78
|
+
| `hour` | `1 hour`, `6 hour` |
|
|
79
|
+
| `day` | `1 day` |
|
|
80
|
+
| `week` | `1 week` |
|
|
81
|
+
|
|
82
|
+
### sql
|
|
83
|
+
|
|
84
|
+
Any SQL that returns a single value. Common patterns:
|
|
85
|
+
|
|
86
|
+
```yaml
|
|
87
|
+
# Max timestamp (for append-only data)
|
|
88
|
+
sql: SELECT MAX(created_at) FROM orders
|
|
89
|
+
|
|
90
|
+
# Row count (for small tables)
|
|
91
|
+
sql: SELECT COUNT(*) FROM orders
|
|
92
|
+
|
|
93
|
+
# Checksum (for frequently updated data)
|
|
94
|
+
sql: SELECT CHECKSUM_AGG(CHECKSUM(*)) FROM orders
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Common Patterns
|
|
98
|
+
|
|
99
|
+
### Real-Time Data
|
|
100
|
+
|
|
101
|
+
```yaml
|
|
102
|
+
refresh_key:
|
|
103
|
+
every: 1 minute
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Daily Batch Data
|
|
107
|
+
|
|
108
|
+
```yaml
|
|
109
|
+
refresh_key:
|
|
110
|
+
every: 1 day
|
|
111
|
+
sql: SELECT MAX(load_date) FROM daily_snapshot
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Event Stream Data
|
|
115
|
+
|
|
116
|
+
```yaml
|
|
117
|
+
refresh_key:
|
|
118
|
+
sql: SELECT MAX(event_id) FROM events
|
|
119
|
+
every: 30 second
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Slowly Changing Data
|
|
123
|
+
|
|
124
|
+
```yaml
|
|
125
|
+
refresh_key:
|
|
126
|
+
every: 6 hour
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Pre-Aggregation Refresh
|
|
130
|
+
|
|
131
|
+
Pre-aggregations have their own refresh_key:
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
pre_aggregations:
|
|
135
|
+
- name: main
|
|
136
|
+
measures:
|
|
137
|
+
- count
|
|
138
|
+
refresh_key:
|
|
139
|
+
every: 1 hour
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Best Practices
|
|
143
|
+
|
|
144
|
+
1. **Match data freshness needs** — don't refresh more often than necessary
|
|
145
|
+
2. **Use SQL-based refresh** — for tables with update timestamps
|
|
146
|
+
3. **Consider pre-aggregations** — they have separate refresh cycles
|
|
147
|
+
4. **Monitor performance** — frequent refreshes impact query latency
|
|
148
|
+
|
|
149
|
+
## See Also
|
|
150
|
+
|
|
151
|
+
- cubes
|
|
152
|
+
- pre-aggregations
|
|
153
|
+
- pre-aggregations.rollup
|
|
154
|
+
|
|
155
|
+
## More Information
|
|
156
|
+
|
|
157
|
+
https://cube.dev/docs/reference/data-model/cube#refresh-key
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# cubes.segments
|
|
2
|
+
|
|
3
|
+
> Define reusable row-level filters.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Segments are predefined filters that can be applied to queries. They make common filtering patterns reusable and ensure consistent definitions across analyses.
|
|
8
|
+
|
|
9
|
+
## Example
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
cubes:
|
|
13
|
+
- name: orders
|
|
14
|
+
sql: SELECT * FROM orders
|
|
15
|
+
|
|
16
|
+
segments:
|
|
17
|
+
- name: completed
|
|
18
|
+
sql: "{CUBE}.status = 'completed'"
|
|
19
|
+
|
|
20
|
+
- name: high_value
|
|
21
|
+
sql: "{CUBE}.amount > 1000"
|
|
22
|
+
|
|
23
|
+
- name: this_year
|
|
24
|
+
sql: "YEAR({CUBE}.created_at) = YEAR(CURRENT_DATE)"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Syntax
|
|
28
|
+
|
|
29
|
+
### Basic Segment
|
|
30
|
+
|
|
31
|
+
```yaml
|
|
32
|
+
segments:
|
|
33
|
+
- name: active
|
|
34
|
+
sql: "{CUBE}.is_active = true"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Multiple Conditions
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
segments:
|
|
41
|
+
- name: premium_active
|
|
42
|
+
sql: "{CUBE}.is_active = true AND {CUBE}.plan = 'premium'"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Using References
|
|
46
|
+
|
|
47
|
+
```yaml
|
|
48
|
+
segments:
|
|
49
|
+
- name: has_recent_order
|
|
50
|
+
sql: "{CUBE}.last_order_date > CURRENT_DATE - INTERVAL '30 days'"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Segments vs Filters
|
|
54
|
+
|
|
55
|
+
| Segments | Query Filters |
|
|
56
|
+
|----------|---------------|
|
|
57
|
+
| Predefined in model | Applied at query time |
|
|
58
|
+
| Named and reusable | Ad-hoc |
|
|
59
|
+
| Part of the schema | Part of the query |
|
|
60
|
+
| Self-documenting | Requires context |
|
|
61
|
+
|
|
62
|
+
## Segments vs Filtered Measures
|
|
63
|
+
|
|
64
|
+
| Use Case | Solution |
|
|
65
|
+
|----------|----------|
|
|
66
|
+
| Filter all measures in a query | Segment |
|
|
67
|
+
| Create a specific filtered metric | Filtered measure |
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
# Segment: filters entire query
|
|
71
|
+
segments:
|
|
72
|
+
- name: completed
|
|
73
|
+
sql: "{CUBE}.status = 'completed'"
|
|
74
|
+
|
|
75
|
+
# Filtered measure: only this metric
|
|
76
|
+
measures:
|
|
77
|
+
- name: completed_count
|
|
78
|
+
type: count
|
|
79
|
+
filters:
|
|
80
|
+
- sql: "{CUBE}.status = 'completed'"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Common Patterns
|
|
84
|
+
|
|
85
|
+
### Status Segments
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
segments:
|
|
89
|
+
- name: pending
|
|
90
|
+
sql: "{CUBE}.status = 'pending'"
|
|
91
|
+
- name: completed
|
|
92
|
+
sql: "{CUBE}.status = 'completed'"
|
|
93
|
+
- name: cancelled
|
|
94
|
+
sql: "{CUBE}.status = 'cancelled'"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Time-based Segments
|
|
98
|
+
|
|
99
|
+
```yaml
|
|
100
|
+
segments:
|
|
101
|
+
- name: last_7_days
|
|
102
|
+
sql: "{CUBE}.created_at >= CURRENT_DATE - INTERVAL '7 days'"
|
|
103
|
+
- name: last_30_days
|
|
104
|
+
sql: "{CUBE}.created_at >= CURRENT_DATE - INTERVAL '30 days'"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Business Logic Segments
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
segments:
|
|
111
|
+
- name: churned
|
|
112
|
+
sql: "{CUBE}.last_activity_at < CURRENT_DATE - INTERVAL '90 days'"
|
|
113
|
+
- name: high_value_customer
|
|
114
|
+
sql: "{CUBE}.lifetime_value > 10000"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## See Also
|
|
118
|
+
|
|
119
|
+
- cubes
|
|
120
|
+
- cubes.measures.filters
|
|
121
|
+
- views
|
|
122
|
+
|
|
123
|
+
## More Information
|
|
124
|
+
|
|
125
|
+
https://cube.dev/docs/reference/data-model/segments
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# cubes.sql
|
|
2
|
+
|
|
3
|
+
> Define the SQL table or subquery that powers a cube.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `sql` property defines the base table or SQL subquery that a cube is built on. This is the foundation for all measures and dimensions in the cube.
|
|
8
|
+
|
|
9
|
+
## Example
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
cubes:
|
|
13
|
+
- name: orders
|
|
14
|
+
sql: SELECT * FROM public.orders
|
|
15
|
+
|
|
16
|
+
- name: orders_with_users
|
|
17
|
+
sql: >
|
|
18
|
+
SELECT o.*, u.name as user_name
|
|
19
|
+
FROM public.orders o
|
|
20
|
+
LEFT JOIN public.users u ON o.user_id = u.id
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Options
|
|
24
|
+
|
|
25
|
+
### sql (required)
|
|
26
|
+
The SQL SELECT statement or table reference.
|
|
27
|
+
|
|
28
|
+
```yaml
|
|
29
|
+
# Simple table reference
|
|
30
|
+
sql: SELECT * FROM orders
|
|
31
|
+
|
|
32
|
+
# Subquery with joins
|
|
33
|
+
sql: >
|
|
34
|
+
SELECT o.*, p.name as product_name
|
|
35
|
+
FROM orders o
|
|
36
|
+
JOIN products p ON o.product_id = p.id
|
|
37
|
+
|
|
38
|
+
# Using references to other cubes
|
|
39
|
+
sql: SELECT * FROM {users.sql()} WHERE active = true
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### sql_table
|
|
43
|
+
Alternative to `sql` — directly reference a table without SELECT.
|
|
44
|
+
|
|
45
|
+
```yaml
|
|
46
|
+
cubes:
|
|
47
|
+
- name: orders
|
|
48
|
+
sql_table: public.orders
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Best Practices
|
|
52
|
+
|
|
53
|
+
1. **Prefer sql_table** when selecting all columns from a single table
|
|
54
|
+
2. **Use subqueries** for complex joins or filtering at the cube level
|
|
55
|
+
3. **Avoid aggregations** in the base SQL — let measures handle that
|
|
56
|
+
|
|
57
|
+
## See Also
|
|
58
|
+
|
|
59
|
+
- cubes
|
|
60
|
+
- cubes.data-source
|
|
61
|
+
- syntax.references
|
|
62
|
+
|
|
63
|
+
## More Information
|
|
64
|
+
|
|
65
|
+
https://cube.dev/docs/reference/data-model/cube#sql
|