@simplysm/orm-common 13.0.98 → 13.0.100
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/README.md +109 -184
- package/docs/core.md +125 -116
- package/docs/expression.md +168 -230
- package/docs/query-builder.md +46 -149
- package/docs/queryable.md +144 -524
- package/docs/schema-builders.md +245 -197
- package/docs/types.md +190 -190
- package/docs/utilities.md +13 -108
- package/package.json +2 -2
package/docs/expression.md
CHANGED
|
@@ -1,48 +1,45 @@
|
|
|
1
1
|
# Expression
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Source: `src/expr/expr-unit.ts`, `src/expr/expr.ts`
|
|
6
|
-
|
|
7
|
-
## ExprUnit
|
|
3
|
+
## `ExprUnit`
|
|
8
4
|
|
|
9
5
|
Type-safe expression wrapper. Tracks expression return type using TypeScript generics.
|
|
10
6
|
|
|
11
7
|
```typescript
|
|
12
8
|
class ExprUnit<TPrimitive extends ColumnPrimitive> {
|
|
13
9
|
readonly $infer!: TPrimitive;
|
|
14
|
-
readonly dataType: ColumnPrimitiveStr;
|
|
15
|
-
readonly expr: Expr;
|
|
16
|
-
|
|
17
|
-
/** Strip undefined from the type (non-null assertion) */
|
|
18
10
|
get n(): ExprUnit<NonNullable<TPrimitive>>;
|
|
19
|
-
|
|
20
|
-
constructor(dataType: ColumnPrimitiveStr, expr: Expr);
|
|
11
|
+
constructor(readonly dataType: ColumnPrimitiveStr, readonly expr: Expr);
|
|
21
12
|
}
|
|
22
13
|
```
|
|
23
14
|
|
|
24
|
-
|
|
15
|
+
| Property | Type | Description |
|
|
16
|
+
|----------|------|-------------|
|
|
17
|
+
| `$infer` | `TPrimitive` | Type inference marker (not used at runtime) |
|
|
18
|
+
| `n` | `ExprUnit<NonNullable<TPrimitive>>` | Non-nullable version of this expression |
|
|
19
|
+
| `dataType` | `ColumnPrimitiveStr` | Column data type name |
|
|
20
|
+
| `expr` | `Expr` | Internal expression AST |
|
|
21
|
+
|
|
22
|
+
## `WhereExprUnit`
|
|
25
23
|
|
|
26
24
|
Expression wrapper for WHERE clause conditions.
|
|
27
25
|
|
|
28
26
|
```typescript
|
|
29
27
|
class WhereExprUnit {
|
|
30
|
-
readonly expr: WhereExpr;
|
|
31
|
-
constructor(expr: WhereExpr);
|
|
28
|
+
constructor(readonly expr: WhereExpr);
|
|
32
29
|
}
|
|
33
30
|
```
|
|
34
31
|
|
|
35
|
-
## ExprInput
|
|
32
|
+
## `ExprInput`
|
|
36
33
|
|
|
37
|
-
Input type that accepts
|
|
34
|
+
Input type that accepts `ExprUnit` or literal values.
|
|
38
35
|
|
|
39
36
|
```typescript
|
|
40
37
|
type ExprInput<TPrimitive extends ColumnPrimitive> = ExprUnit<TPrimitive> | TPrimitive;
|
|
41
38
|
```
|
|
42
39
|
|
|
43
|
-
## SwitchExprBuilder
|
|
40
|
+
## `SwitchExprBuilder`
|
|
44
41
|
|
|
45
|
-
|
|
42
|
+
CASE/WHEN expression builder interface.
|
|
46
43
|
|
|
47
44
|
```typescript
|
|
48
45
|
interface SwitchExprBuilder<TPrimitive extends ColumnPrimitive> {
|
|
@@ -51,246 +48,187 @@ interface SwitchExprBuilder<TPrimitive extends ColumnPrimitive> {
|
|
|
51
48
|
}
|
|
52
49
|
```
|
|
53
50
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
## expr
|
|
57
|
-
|
|
58
|
-
The main expression builder object. All methods return `ExprUnit` or `WhereExprUnit`.
|
|
59
|
-
|
|
60
|
-
### Value Creation
|
|
61
|
-
|
|
62
|
-
| Method | Signature | Description |
|
|
63
|
-
|--------|-----------|-------------|
|
|
64
|
-
| `val` | `val<TStr>(dataType: TStr, value: T): ExprUnit` | Wrap literal value as expression |
|
|
65
|
-
| `col` | `col<TStr>(dataType: ColumnPrimitiveStr, ...path: string[]): ExprUnit` | Column reference (internal use) |
|
|
66
|
-
| `raw` | `raw<T>(dataType: T): (strings, ...values) => ExprUnit` | Raw SQL tagged template (escape hatch) |
|
|
67
|
-
|
|
68
|
-
```typescript
|
|
69
|
-
expr.val("string", "active")
|
|
70
|
-
expr.val("number", 100)
|
|
71
|
-
expr.val("DateTime", DateTime.now())
|
|
72
|
-
|
|
73
|
-
// Raw SQL
|
|
74
|
-
expr.raw("string")`JSON_EXTRACT(${u.metadata}, '$.email')`
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Comparison Operators (WHERE)
|
|
78
|
-
|
|
79
|
-
| Method | SQL | Description |
|
|
80
|
-
|--------|-----|-------------|
|
|
81
|
-
| `eq(source, target)` | `<=>` / `IS NULL OR =` | Equality (NULL-safe) |
|
|
82
|
-
| `gt(source, target)` | `>` | Greater than |
|
|
83
|
-
| `lt(source, target)` | `<` | Less than |
|
|
84
|
-
| `gte(source, target)` | `>=` | Greater than or equal |
|
|
85
|
-
| `lte(source, target)` | `<=` | Less than or equal |
|
|
86
|
-
| `between(source, from?, to?)` | `BETWEEN` | Range (undefined = unbounded) |
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
db.user().where((u) => [
|
|
90
|
-
expr.eq(u.status, "active"),
|
|
91
|
-
expr.gte(u.age, 18),
|
|
92
|
-
expr.between(u.score, 60, 100),
|
|
93
|
-
])
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### NULL Check
|
|
97
|
-
|
|
98
|
-
| Method | SQL | Description |
|
|
99
|
-
|--------|-----|-------------|
|
|
100
|
-
| `null(source)` | `IS NULL` | Check if value is NULL |
|
|
101
|
-
|
|
102
|
-
### String Search (WHERE)
|
|
103
|
-
|
|
104
|
-
| Method | SQL | Description |
|
|
105
|
-
|--------|-----|-------------|
|
|
106
|
-
| `like(source, pattern)` | `LIKE ... ESCAPE '\'` | Pattern matching (`%`, `_` wildcards) |
|
|
107
|
-
| `regexp(source, pattern)` | `REGEXP` | Regular expression matching |
|
|
108
|
-
|
|
109
|
-
### IN / EXISTS (WHERE)
|
|
51
|
+
## `expr`
|
|
110
52
|
|
|
111
|
-
|
|
112
|
-
|--------|-----|-------------|
|
|
113
|
-
| `in(source, values)` | `IN (...)` | Value list inclusion |
|
|
114
|
-
| `inQuery(source, query)` | `IN (SELECT ...)` | Subquery inclusion (single column) |
|
|
115
|
-
| `exists(query)` | `EXISTS (SELECT ...)` | Subquery existence check |
|
|
53
|
+
Dialect-independent SQL expression builder. Generates JSON AST (`Expr`) instead of SQL strings, which `QueryBuilder` converts to each DBMS (MySQL, MSSQL, PostgreSQL).
|
|
116
54
|
|
|
117
55
|
```typescript
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
),
|
|
123
|
-
|
|
56
|
+
const expr: {
|
|
57
|
+
// Value creation
|
|
58
|
+
val<TStr extends ColumnPrimitiveStr>(dataType: TStr, value): ExprUnit<...>;
|
|
59
|
+
col<TStr extends ColumnPrimitiveStr>(dataType: ColumnPrimitiveStr, ...path: string[]): ExprUnit<...>;
|
|
60
|
+
raw<T extends ColumnPrimitiveStr>(dataType: T): (strings: TemplateStringsArray, ...values: ExprInput<ColumnPrimitive>[]) => ExprUnit<...>;
|
|
61
|
+
|
|
62
|
+
// Comparison (WHERE)
|
|
63
|
+
eq<T extends ColumnPrimitive>(source: ExprUnit<T>, target: ExprInput<T>): WhereExprUnit;
|
|
64
|
+
gt<T extends ColumnPrimitive>(source: ExprUnit<T>, target: ExprInput<T>): WhereExprUnit;
|
|
65
|
+
lt<T extends ColumnPrimitive>(source: ExprUnit<T>, target: ExprInput<T>): WhereExprUnit;
|
|
66
|
+
gte<T extends ColumnPrimitive>(source: ExprUnit<T>, target: ExprInput<T>): WhereExprUnit;
|
|
67
|
+
lte<T extends ColumnPrimitive>(source: ExprUnit<T>, target: ExprInput<T>): WhereExprUnit;
|
|
68
|
+
between<T extends ColumnPrimitive>(source: ExprUnit<T>, from?: ExprInput<T>, to?: ExprInput<T>): WhereExprUnit;
|
|
69
|
+
isNull(arg: ExprUnit<ColumnPrimitive>): WhereExprUnit;
|
|
70
|
+
like(source: ExprUnit<string | undefined>, pattern: ExprInput<string>): WhereExprUnit;
|
|
71
|
+
regexp(source: ExprUnit<string | undefined>, pattern: ExprInput<string>): WhereExprUnit;
|
|
72
|
+
in<T extends ColumnPrimitive>(source: ExprUnit<T>, values: ExprInput<T>[]): WhereExprUnit;
|
|
73
|
+
inQuery<T extends ColumnPrimitive>(source: ExprUnit<T>, query: Queryable<any, any>): WhereExprUnit;
|
|
74
|
+
exists(query: Queryable<any, any>): WhereExprUnit;
|
|
75
|
+
|
|
76
|
+
// Logical
|
|
77
|
+
not(condition: WhereExprUnit): WhereExprUnit;
|
|
78
|
+
and(...conditions: WhereExprUnit[]): WhereExprUnit;
|
|
79
|
+
or(...conditions: WhereExprUnit[]): WhereExprUnit;
|
|
80
|
+
|
|
81
|
+
// String
|
|
82
|
+
concat(...args: ExprInput<string | undefined>[]): ExprUnit<string>;
|
|
83
|
+
left(source: ExprInput<string | undefined>, length: ExprInput<number>): ExprUnit<string>;
|
|
84
|
+
right(source: ExprInput<string | undefined>, length: ExprInput<number>): ExprUnit<string>;
|
|
85
|
+
trim(arg: ExprInput<string | undefined>): ExprUnit<string>;
|
|
86
|
+
padStart(source: ExprInput<string | undefined>, length: ExprInput<number>, fillString: ExprInput<string>): ExprUnit<string>;
|
|
87
|
+
replace(source: ExprInput<string | undefined>, from: ExprInput<string>, to: ExprInput<string>): ExprUnit<string>;
|
|
88
|
+
upper(arg: ExprInput<string | undefined>): ExprUnit<string>;
|
|
89
|
+
lower(arg: ExprInput<string | undefined>): ExprUnit<string>;
|
|
90
|
+
length(arg: ExprInput<string | undefined>): ExprUnit<number>;
|
|
91
|
+
byteLength(arg: ExprInput<string | undefined>): ExprUnit<number>;
|
|
92
|
+
substring(source: ExprInput<string | undefined>, start: ExprInput<number>, length?: ExprInput<number>): ExprUnit<string>;
|
|
93
|
+
indexOf(source: ExprInput<string | undefined>, search: ExprInput<string>): ExprUnit<number>;
|
|
94
|
+
|
|
95
|
+
// Numeric
|
|
96
|
+
abs(arg: ExprInput<number | undefined>): ExprUnit<number>;
|
|
97
|
+
round(arg: ExprInput<number | undefined>, digits: number): ExprUnit<number>;
|
|
98
|
+
ceil(arg: ExprInput<number | undefined>): ExprUnit<number>;
|
|
99
|
+
floor(arg: ExprInput<number | undefined>): ExprUnit<number>;
|
|
100
|
+
|
|
101
|
+
// Date
|
|
102
|
+
year(arg: ExprInput<DateTime | DateOnly | undefined>): ExprUnit<number>;
|
|
103
|
+
month(arg: ExprInput<DateTime | DateOnly | undefined>): ExprUnit<number>;
|
|
104
|
+
day(arg: ExprInput<DateTime | DateOnly | undefined>): ExprUnit<number>;
|
|
105
|
+
hour(arg: ExprInput<DateTime | undefined>): ExprUnit<number>;
|
|
106
|
+
minute(arg: ExprInput<DateTime | undefined>): ExprUnit<number>;
|
|
107
|
+
second(arg: ExprInput<DateTime | undefined>): ExprUnit<number>;
|
|
108
|
+
isoWeek(arg: ExprInput<DateTime | DateOnly | undefined>): ExprUnit<number>;
|
|
109
|
+
isoWeekStartDate(arg: ExprInput<DateTime | DateOnly | undefined>): ExprUnit<DateOnly>;
|
|
110
|
+
isoYearMonth(arg: ExprInput<DateTime | DateOnly | undefined>): ExprUnit<string>;
|
|
111
|
+
dateDiff(unit: DateUnit, from: ExprInput<ColumnPrimitive>, to: ExprInput<ColumnPrimitive>): ExprUnit<number>;
|
|
112
|
+
dateAdd(unit: DateUnit, source: ExprInput<ColumnPrimitive>, value: ExprInput<number>): ExprUnit<DateTime>;
|
|
113
|
+
formatDate(source: ExprInput<ColumnPrimitive>, format: string): ExprUnit<string>;
|
|
114
|
+
|
|
115
|
+
// Conditional
|
|
116
|
+
coalesce<T extends ColumnPrimitive>(...args: ExprInput<T | undefined>[]): ExprUnit<T>;
|
|
117
|
+
nullIf<T extends ColumnPrimitive>(source: ExprInput<T>, value: ExprInput<T>): ExprUnit<T | undefined>;
|
|
118
|
+
is(condition: WhereExprUnit): ExprUnit<number>;
|
|
119
|
+
switch<T extends ColumnPrimitive>(dataType: ColumnPrimitiveStr): SwitchExprBuilder<T>;
|
|
120
|
+
if<T extends ColumnPrimitive>(condition: WhereExprUnit, then: ExprInput<T>, elseVal?: ExprInput<T>): ExprUnit<T>;
|
|
121
|
+
|
|
122
|
+
// Aggregate
|
|
123
|
+
count(arg?: ExprUnit<ColumnPrimitive>, distinct?: boolean): ExprUnit<number>;
|
|
124
|
+
sum(arg: ExprUnit<number | undefined>): ExprUnit<number>;
|
|
125
|
+
avg(arg: ExprUnit<number | undefined>): ExprUnit<number>;
|
|
126
|
+
max<T extends ColumnPrimitive>(arg: ExprUnit<T>): ExprUnit<T>;
|
|
127
|
+
min<T extends ColumnPrimitive>(arg: ExprUnit<T>): ExprUnit<T>;
|
|
128
|
+
|
|
129
|
+
// Other
|
|
130
|
+
greatest<T extends ColumnPrimitive>(...args: ExprInput<T>[]): ExprUnit<T>;
|
|
131
|
+
least<T extends ColumnPrimitive>(...args: ExprInput<T>[]): ExprUnit<T>;
|
|
132
|
+
rowNum(): ExprUnit<number>;
|
|
133
|
+
random(): ExprUnit<number>;
|
|
134
|
+
cast<TDataType extends DataType>(source: ExprInput<ColumnPrimitive>, targetType: TDataType): ExprUnit<InferColumnPrimitiveFromDataType<TDataType>>;
|
|
135
|
+
|
|
136
|
+
// Window
|
|
137
|
+
window(fn: WinFn, spec?: WinSpecInput): ExprUnit<number>;
|
|
138
|
+
|
|
139
|
+
// Subquery
|
|
140
|
+
subquery<T extends ColumnPrimitive>(query: Queryable<any, any>, selectFn: (q: ...) => ExprUnit<T>): ExprUnit<T>;
|
|
141
|
+
};
|
|
124
142
|
```
|
|
125
143
|
|
|
126
|
-
###
|
|
144
|
+
### Value Creation
|
|
127
145
|
|
|
128
|
-
| Method |
|
|
129
|
-
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
146
|
+
| Method | Description |
|
|
147
|
+
|--------|-------------|
|
|
148
|
+
| `val()` | Wrap literal value as ExprUnit |
|
|
149
|
+
| `col()` | Generate column reference |
|
|
150
|
+
| `raw()` | Raw SQL expression (escape hatch, tagged template literal) |
|
|
133
151
|
|
|
134
|
-
###
|
|
152
|
+
### Comparison (WHERE)
|
|
135
153
|
|
|
136
154
|
| Method | SQL | Description |
|
|
137
155
|
|--------|-----|-------------|
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
149
|
-
| `
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
db.user().select((u) => ({
|
|
153
|
-
fullName: expr.concat(u.firstName, " ", u.lastName),
|
|
154
|
-
initial: expr.left(u.name, 1),
|
|
155
|
-
email: expr.lower(u.email),
|
|
156
|
-
}))
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### Numeric Functions (SELECT)
|
|
156
|
+
| `eq()` | `=` | Equality comparison (NULL-safe) |
|
|
157
|
+
| `gt()` | `>` | Greater than |
|
|
158
|
+
| `lt()` | `<` | Less than |
|
|
159
|
+
| `gte()` | `>=` | Greater than or equal |
|
|
160
|
+
| `lte()` | `<=` | Less than or equal |
|
|
161
|
+
| `between()` | `BETWEEN` | Range comparison |
|
|
162
|
+
| `isNull()` | `IS NULL` | NULL check |
|
|
163
|
+
| `like()` | `LIKE` | Pattern matching |
|
|
164
|
+
| `regexp()` | `REGEXP` | Regular expression matching |
|
|
165
|
+
| `in()` | `IN` | Value list inclusion |
|
|
166
|
+
| `inQuery()` | `IN (SELECT)` | Subquery inclusion |
|
|
167
|
+
| `exists()` | `EXISTS` | Subquery existence |
|
|
168
|
+
|
|
169
|
+
### Logical
|
|
160
170
|
|
|
161
171
|
| Method | SQL | Description |
|
|
162
172
|
|--------|-----|-------------|
|
|
163
|
-
| `
|
|
164
|
-
| `
|
|
165
|
-
| `
|
|
166
|
-
| `floor(source)` | `FLOOR(...)` | Floor |
|
|
173
|
+
| `not()` | `NOT` | Logical negation |
|
|
174
|
+
| `and()` | `AND` | Logical conjunction |
|
|
175
|
+
| `or()` | `OR` | Logical disjunction |
|
|
167
176
|
|
|
168
|
-
###
|
|
177
|
+
### String Functions
|
|
169
178
|
|
|
170
179
|
| Method | SQL | Description |
|
|
171
180
|
|--------|-----|-------------|
|
|
172
|
-
| `
|
|
173
|
-
| `
|
|
174
|
-
| `
|
|
175
|
-
| `
|
|
176
|
-
| `
|
|
177
|
-
| `
|
|
178
|
-
| `
|
|
179
|
-
| `
|
|
180
|
-
| `
|
|
181
|
-
| `
|
|
182
|
-
| `
|
|
183
|
-
| `
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
```typescript
|
|
188
|
-
db.user().select((u) => ({
|
|
189
|
-
age: expr.dateDiff("year", u.birthDate, expr.val("DateOnly", DateOnly.today())),
|
|
190
|
-
expiresAt: expr.dateAdd("month", u.startDate, 12),
|
|
191
|
-
}))
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
### Conditional Functions (SELECT)
|
|
181
|
+
| `concat()` | `CONCAT` | String concatenation |
|
|
182
|
+
| `left()` | `LEFT` | Extract left N characters |
|
|
183
|
+
| `right()` | `RIGHT` | Extract right N characters |
|
|
184
|
+
| `trim()` | `TRIM` | Remove leading/trailing whitespace |
|
|
185
|
+
| `padStart()` | `LPAD` | Left padding |
|
|
186
|
+
| `replace()` | `REPLACE` | String replacement |
|
|
187
|
+
| `upper()` | `UPPER` | Uppercase |
|
|
188
|
+
| `lower()` | `LOWER` | Lowercase |
|
|
189
|
+
| `length()` | `CHAR_LENGTH` | Character length |
|
|
190
|
+
| `byteLength()` | `LENGTH/DATALENGTH` | Byte length |
|
|
191
|
+
| `substring()` | `SUBSTRING` | Substring extraction |
|
|
192
|
+
| `indexOf()` | `LOCATE/CHARINDEX` | Find string position |
|
|
193
|
+
|
|
194
|
+
### Numeric Functions
|
|
195
195
|
|
|
196
196
|
| Method | SQL | Description |
|
|
197
197
|
|--------|-----|-------------|
|
|
198
|
-
| `
|
|
199
|
-
| `
|
|
200
|
-
| `
|
|
201
|
-
| `
|
|
202
|
-
| `if(condition, then, else_)` | `IF(...)`/`IIF(...)` | Ternary conditional |
|
|
203
|
-
|
|
204
|
-
```typescript
|
|
205
|
-
db.user().select((u) => ({
|
|
206
|
-
displayName: expr.coalesce(u.nickname, u.name, "Guest"),
|
|
207
|
-
isActive: expr.is(expr.eq(u.status, "active")),
|
|
208
|
-
grade: expr.switch<string>()
|
|
209
|
-
.case(expr.gte(u.score, 90), "A")
|
|
210
|
-
.case(expr.gte(u.score, 80), "B")
|
|
211
|
-
.default("C"),
|
|
212
|
-
}))
|
|
213
|
-
```
|
|
198
|
+
| `abs()` | `ABS` | Absolute value |
|
|
199
|
+
| `round()` | `ROUND` | Rounding |
|
|
200
|
+
| `ceil()` | `CEIL` | Ceiling |
|
|
201
|
+
| `floor()` | `FLOOR` | Floor |
|
|
214
202
|
|
|
215
|
-
###
|
|
203
|
+
### Date Functions
|
|
216
204
|
|
|
217
205
|
| Method | SQL | Description |
|
|
218
206
|
|--------|-----|-------------|
|
|
219
|
-
| `
|
|
220
|
-
| `
|
|
221
|
-
| `
|
|
222
|
-
| `
|
|
223
|
-
| `
|
|
224
|
-
|
|
225
|
-
|
|
207
|
+
| `year()` | `YEAR` | Extract year |
|
|
208
|
+
| `month()` | `MONTH` | Extract month |
|
|
209
|
+
| `day()` | `DAY` | Extract day |
|
|
210
|
+
| `hour()` | `HOUR` | Extract hour |
|
|
211
|
+
| `minute()` | `MINUTE` | Extract minute |
|
|
212
|
+
| `second()` | `SECOND` | Extract second |
|
|
213
|
+
| `isoWeek()` | `WEEK` | ISO week number |
|
|
214
|
+
| `isoWeekStartDate()` | - | ISO week start date |
|
|
215
|
+
| `isoYearMonth()` | - | ISO year-month (YYYYMM) |
|
|
216
|
+
| `dateDiff()` | `DATEDIFF` | Date difference |
|
|
217
|
+
| `dateAdd()` | `DATEADD` | Date arithmetic |
|
|
218
|
+
| `formatDate()` | `FORMAT/DATE_FORMAT` | Date formatting |
|
|
219
|
+
|
|
220
|
+
### Aggregate Functions
|
|
226
221
|
|
|
227
222
|
| Method | SQL | Description |
|
|
228
223
|
|--------|-----|-------------|
|
|
229
|
-
| `
|
|
230
|
-
| `
|
|
231
|
-
| `
|
|
232
|
-
| `
|
|
233
|
-
| `
|
|
234
|
-
| `subquery(dataType, queryable)` | `(SELECT ...)` | Scalar subquery |
|
|
235
|
-
|
|
236
|
-
```typescript
|
|
237
|
-
db.user().select((u) => ({
|
|
238
|
-
id: u.id,
|
|
239
|
-
postCount: expr.subquery("number",
|
|
240
|
-
db.post()
|
|
241
|
-
.where((p) => [expr.eq(p.userId, u.id)])
|
|
242
|
-
.select(() => ({ cnt: expr.count() }))
|
|
243
|
-
),
|
|
244
|
-
}))
|
|
245
|
-
```
|
|
224
|
+
| `count()` | `COUNT` | Record count |
|
|
225
|
+
| `sum()` | `SUM` | Sum |
|
|
226
|
+
| `avg()` | `AVG` | Average |
|
|
227
|
+
| `max()` | `MAX` | Maximum |
|
|
228
|
+
| `min()` | `MIN` | Minimum |
|
|
246
229
|
|
|
247
|
-
### Window Functions
|
|
248
|
-
|
|
249
|
-
All window functions accept a `WinSpecInput`:
|
|
250
|
-
|
|
251
|
-
```typescript
|
|
252
|
-
interface WinSpecInput {
|
|
253
|
-
partitionBy?: ExprInput<ColumnPrimitive>[];
|
|
254
|
-
orderBy?: [ExprInput<ColumnPrimitive>, ("ASC" | "DESC")?][];
|
|
255
|
-
}
|
|
256
|
-
```
|
|
230
|
+
### Window Functions
|
|
257
231
|
|
|
258
232
|
| Method | SQL | Description |
|
|
259
233
|
|--------|-----|-------------|
|
|
260
|
-
| `
|
|
261
|
-
| `rank(spec)` | `RANK() OVER(...)` | Rank (ties skip: 1,1,3) |
|
|
262
|
-
| `denseRank(spec)` | `DENSE_RANK() OVER(...)` | Dense rank (ties consecutive: 1,1,2) |
|
|
263
|
-
| `ntile(n, spec)` | `NTILE(n) OVER(...)` | Split into n groups |
|
|
264
|
-
| `lag(column, spec, options?)` | `LAG() OVER(...)` | Previous row value |
|
|
265
|
-
| `lead(column, spec, options?)` | `LEAD() OVER(...)` | Next row value |
|
|
266
|
-
| `firstValue(column, spec)` | `FIRST_VALUE() OVER(...)` | First value in frame |
|
|
267
|
-
| `lastValue(column, spec)` | `LAST_VALUE() OVER(...)` | Last value in frame |
|
|
268
|
-
| `sumOver(column, spec)` | `SUM() OVER(...)` | Window sum |
|
|
269
|
-
| `avgOver(column, spec)` | `AVG() OVER(...)` | Window average |
|
|
270
|
-
| `countOver(spec, column?)` | `COUNT() OVER(...)` | Window count |
|
|
271
|
-
| `minOver(column, spec)` | `MIN() OVER(...)` | Window minimum |
|
|
272
|
-
| `maxOver(column, spec)` | `MAX() OVER(...)` | Window maximum |
|
|
273
|
-
|
|
274
|
-
`lag` and `lead` options:
|
|
275
|
-
- `offset?: number` -- default 1
|
|
276
|
-
- `default?: ExprInput<T>` -- default value when no row exists
|
|
277
|
-
|
|
278
|
-
```typescript
|
|
279
|
-
db.order().select((o) => ({
|
|
280
|
-
...o,
|
|
281
|
-
rowNum: expr.rowNumber({
|
|
282
|
-
partitionBy: [o.userId],
|
|
283
|
-
orderBy: [[o.createdAt, "DESC"]],
|
|
284
|
-
}),
|
|
285
|
-
runningTotal: expr.sumOver(o.amount, {
|
|
286
|
-
partitionBy: [o.userId],
|
|
287
|
-
orderBy: [[o.createdAt, "ASC"]],
|
|
288
|
-
}),
|
|
289
|
-
}))
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
### Helper
|
|
293
|
-
|
|
294
|
-
| Method | Description |
|
|
295
|
-
|--------|-------------|
|
|
296
|
-
| `toExpr(value: ExprInput<ColumnPrimitive>): Expr` | Convert ExprInput to Expr JSON AST (internal use) |
|
|
234
|
+
| `window()` | `OVER(...)` | Window function (rowNumber, rank, denseRank, ntile, lag, lead, firstValue, lastValue, sum, avg, count, min, max) |
|