Skip to content

Commit 4455827

Browse files
merge: from main to 3.0 #35103
2 parents b0a879b + 5ce853d commit 4455827

34 files changed

Lines changed: 1916 additions & 665 deletions

File tree

.github/workflows/tdengine-docs-ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ jobs:
169169
if: ${{ steps.check-doc-lang.outputs.zh_doc_changed == 'true'}}
170170
run: |
171171
cd ${{ env.DOC_WKC }}/${{ env.ZH_DOC_REPO }}
172-
rm -rf docs/* && git restore docs/
172+
rm -rf build/* && rm -rf docs/* && git restore docs/
173173
git checkout -f master && git pull origin master
174174
yarn install
175175
yarn ass local
@@ -178,8 +178,8 @@ jobs:
178178
if: ${{ steps.check-doc-lang.outputs.en_doc_changed == 'true'}}
179179
run: |
180180
cd ${{ env.DOC_WKC }}/${{ env.EN_DOC_REPO }}
181-
rm -rf docs/* && git restore docs/
181+
rm -rf build/* && rm -rf docs/* && git restore docs/
182182
git checkout -f main && git pull origin main
183183
yarn install
184184
yarn ass local
185-
yarn build
185+
yarn build

docs/en/05-basic/03-query.md

Lines changed: 21 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ The window clause allows you to partition the queried data set by windows and ag
151151
- Session Window: Sessions are divided based on the differences in record timestamps, with records having a timestamp interval less than the predefined value belonging to the same session.
152152
- Event Window: Windows are dynamically divided based on the start and end conditions of events, opening when the start condition is met and closing when the end condition is met.
153153
- Count Window: Windows are divided based on the number of data rows, with each window consisting of a specified number of rows for aggregation calculations.
154+
- External Window: The time range of the window is explicitly defined by a subquery, which is suitable for complex analysis such as cross-event correlation, window reuse, and layered filtering.
154155

155156
The syntax for the window clause is as follows:
156157

@@ -160,12 +161,14 @@ window_clause: {
160161
| STATE_WINDOW(expr [, extend[, zeroth_state]]) [TRUE_FOR(true_for_expr)]
161162
| INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [fill_clause]
162163
| EVENT_WINDOW START WITH start_trigger_condition END WITH end_trigger_condition [TRUE_FOR(true_for_expr)]
164+
| COUNT_WINDOW(count_val[, sliding_val])
165+
| EXTERNAL_WINDOW ((subquery) window_alias)
163166
}
164167
```
165168

166169
:::note
167170

168-
When using the window clause, the following rules should be observed:
171+
When using the window clause, the following rules should be observed. These rules apply to the five window types SESSION, STATE_WINDOW, INTERVAL, EVENT_WINDOW, and COUNT_WINDOW. EXTERNAL_WINDOW has different rules; see the [External Window](#external-window) section for details.
169172

170173
1. The window clause is located after the data partitioning clause and cannot be used together with the GROUP BY clause.
171174
1. The window clause partitions the data by windows and performs calculations on the expressions in the SELECT list for each window. The expressions in the SELECT list can only include: constants; pseudocolumns: \_wstart pseudo-column,\_wend pseudo-column, and \_wduration pseudo-column; aggregate functions (including selection functions and time-series specific functions that can determine the number of output rows by parameters)
@@ -528,7 +531,7 @@ Query OK, 10 row(s) in set (0.062794s)
528531

529532
### External Window
530533

531-
External Window is a flexible windowing mechanism provided by TDengine TSDB that allows users to perform complex aggregation and correlation queries based on explicitly defined time windows. Unlike standard windows, external windows allow users to explicitly define the window start and end times through subqueries, enabling more sophisticated processing and analysis of time-series data.
534+
External Window is used to "define windows first, then calculate within the windows." Unlike built-in windows such as INTERVAL and EVENT_WINDOW, the time range of an external window is explicitly defined by a subquery, which is suitable for complex analysis such as cross-event correlation, window reuse, and layered filtering.
532535

533536
**Syntax:**
534537

@@ -543,85 +546,32 @@ EXTERNAL_WINDOW (
543546
[ORDER BY ...]
544547
```
545548

546-
Where:
549+
The first two columns of the subquery must be of type timestamp, representing the window start time and window end time respectively. Columns from the third column onward become "window attribute columns", which can be referenced through `window_alias.column_name`. The outer query performs calculations independently within each window range.
547550

548-
- The first two columns of the subquery must be of timestamp type, representing the window start time and window end time respectively
549-
- Columns from the 3rd column onward become "window attribute columns"
550-
- The outer query performs independent calculations within each window range
551-
552-
**Key Features:**
553-
554-
1. **Flexible Window Definition:** Supports defining windows through regular subqueries, INTERVAL, EVENT_WINDOW, SESSION, and other window types.
555-
556-
2. **Aggregation and Computation:** Supports aggregate functions like COUNT, AVG, SUM, MAX, MIN, FIRST, LAST, and scalar expressions.
557-
558-
3. **Pseudo-column Support:** `_wstart` (window start time), `_wend` (window end time), and `_wduration` (window duration) can be used in SELECT, HAVING, and ORDER BY clauses.
559-
560-
4. **Grouping and Alignment:**
561-
- The subquery can use `PARTITION BY` or `GROUP BY` for grouping, while the outer query can only use `PARTITION BY` for grouping.
562-
- When both the subquery and the outer query use grouping, alignment is performed by grouping key: data from the same group only matches windows for that group.
563-
- If a group has no matching data within a particular window, that group will not produce a result row for that window (it is silently omitted).
564-
- When the subquery does not use grouping, the subquery generates a single shared set of windows; if the outer query uses partitioning, each outer partition performs its computations independently over this shared window set.
565-
- When the subquery uses grouping but the outer query does not use grouping, it is prohibited by syntax.
566-
- **Current Limitation**: When both the inner and outer queries use grouping and the window subquery also uses `ORDER BY`, the sorting may disrupt the original organization of each partition's window stream; the outer query may operate on the merged window stream, causing the internal partition semantics to fail (treated as unpartitioned), and the per-group alignment between inner and outer partitions is lost.
567-
568-
5. **Nested Calls Support:** Multiple levels of external window nesting are supported, meaning the subquery of an external window can itself use EXTERNAL_WINDOW, enabling layered aggregation. For example: the first-level external window defines time ranges by events and aggregates intermediate metrics, then the second-level external window performs secondary aggregation on those intermediate metrics within new time ranges.
569-
570-
#### How to Reference Window Attribute Columns
571-
572-
Columns after the first two columns in the subquery (e.g., `groupid`, `location`) become window attribute columns. The referencing rules are:
573-
574-
1. Must be referenced column-by-column using the window alias in the format `window_alias.column_name`, e.g., `w.groupid`, `w.location`.
575-
2. Window attribute columns can only appear in the form `w.column_name` in the outer query's SELECT, HAVING, and ORDER BY clauses.
576-
3. **Cannot be referenced in the WHERE clause** (WHERE filters outer table records before windows are generated; window attributes are only available after window definition and should be used in HAVING).
577-
4. In the current implementation, the window alias is not a complete "virtual table" — **the `w.*` wildcard is not supported for expanding all window attribute columns**, nor can `w` be referenced as a standalone table in FROM/JOIN. If needed, explicitly select columns in the subquery and reference them column-by-column in the outer query.
578-
579-
**Usage Example:**
580-
581-
**Scenario Background** - Smart Meter Monitoring System:
582-
583-
Following the smart meter data model used throughout this chapter. The supertable `meters` contains columns `ts`, `current`, `voltage`, `phase`, with tags `groupid` and `location`. Assume there is also an alert events table `alerts` (supertable), containing columns `ts`, `alert_code`, `alert_value`, with tags `groupid` and `location`.
584-
585-
**Objective** - Use voltage anomaly events for each meter group as time windows (within 60 seconds from the moment voltage >= 225V), and collect alert statistics within each window. Output should include: group information, number of alerts in the window, and maximum alert value. Filter for windows where "alerts were triggered", sorted by group and time.
586-
587-
**Note**: This example intentionally omits `ORDER BY` from the window subquery. In this scenario, the subquery already outputs the window stream in partition order; adding an explicit sort would trigger the "partition alignment failure" limitation described above.
551+
Example: the `grid_events` table records the start and end times of power grid events such as outages or maintenance. Use those event intervals as windows to aggregate voltage data in `meters`, and filter out events with no data in the window:
588552

589553
```sql
590-
SELECT
591-
w.groupid,
592-
w.location,
593-
_wstart AS event_start_time,
594-
COUNT(a.*) AS alert_count,
595-
MAX(a.alert_value) AS max_alert_value,
596-
AVG(a.alert_value) AS avg_alert_value
597-
FROM alerts a
598-
PARTITION BY a.groupid
554+
SELECT _wstart, _wend, COUNT(*), AVG(voltage)
555+
FROM meters
599556
EXTERNAL_WINDOW (
600-
(SELECT ts, ts + 60s, groupid, location
601-
FROM meters
602-
WHERE voltage >= 225
603-
PARTITION BY groupid
604-
) w
557+
(SELECT start_time, end_time FROM grid_events) w
605558
)
606-
HAVING COUNT(a.*) > 0
607-
ORDER BY w.groupid, event_start_time;
559+
HAVING COUNT(*) > 0;
608560
```
609561

610-
**Result Explanation:**
562+
The query result is as follows:
611563

612-
- Each row represents a voltage anomaly event window (driven by records in `meters` where `voltage >= 225`), with a window duration of 60 seconds after the event
613-
- `alert_count`, `max_alert_value`, `avg_alert_value`: statistical metrics from `alerts` within the window
614-
- `w.groupid`, `w.location`: window attribute columns from the subquery's tag columns, used to display group information
615-
- `HAVING` condition uses the aggregate function (`COUNT`) to filter windows with at least one alert
616-
- `PARTITION BY` alignment: both inner and outer queries group by `groupid`, ensuring that each meter group's alerts only match that group's anomaly windows
564+
```text
565+
_wstart | _wend | count(*) | avg(voltage) |
566+
=============================================================================================
567+
2022-03-01 02:00:00.000 | 2022-03-01 02:35:00.000 | 210 | 231.480000000000000 |
568+
2022-06-15 14:10:00.000 | 2022-06-15 14:52:00.000 | 252 | 248.920000000000000 |
569+
...
570+
```
617571

618-
#### Constraints and Limitations
572+
In the SQL above, the window boundaries come from the independent `grid_events` table rather than being derived from `meters` itself. This is the core value of external windows: **decoupling window definition from data sources**. You can directly use the time ranges of arbitrary external events, such as alert records, schedules, or maintenance plans, for aggregation analysis without pre-partitioning the measurement data into windows.
619573

620-
- Currently not supported in stream processing and subscriptions
621-
- The first two columns of the window subquery must be of timestamp type, representing window start and end times
622-
- The window rows returned by the subquery must be kept in order: in the ungrouped case, sorted by window start time (i.e., the first column) in ascending order; in the grouped case, sorted within each group by window start time in ascending order; if these conditions are not met, an error is reported during execution
623-
- If the external window (inner subquery) uses grouping, the outer query must also use PARTITION BY; otherwise, a syntax error occurs
624-
- Variable-length functions (like DIFF, INTERP) are not supported within window scope
574+
For detailed explanations of external window core features such as partition alignment, window attribute column reference rules, nested usage, and constraints, see [TDengine TSDB Distinctive Queries - External Window](../14-reference/03-taos-sql/24-distinguished.md#external-window).
625575

626576
## Time Range Expression
627577

docs/en/14-reference/03-taos-sql/20-select.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ window_clause: {
5858
| INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [WATERMARK(watermark_val)] [fill_clause]
5959
| EVENT_WINDOW START WITH start_trigger_condition END WITH end_trigger_condition [TRUE_FOR(true_for_expr)]
6060
| COUNT_WINDOW(count_val[, sliding_val][, col_name ...])
61+
| EXTERNAL_WINDOW ((subquery) window_alias)
6162
}
6263

6364
interp_clause:
@@ -124,6 +125,7 @@ true_for_expr: {
124125

125126
Where `duration_time` is a positive time value with supported units: 1n (nanoseconds), 1u (microseconds), 1a (milliseconds), 1s (seconds), 1m (minutes), 1h (hours), 1d (days), 1w (weeks). Examples: `TRUE_FOR(10m)`, `TRUE_FOR(COUNT 100)`, `TRUE_FOR(10m AND COUNT 50)`, `TRUE_FOR(5m OR COUNT 20)`.
126127
- COUNT_WINDOW: Count window, specifying the division of the window by the number of rows, count_val window contains the maximum number of rows, with a range of [2,2147483647]. The sliding quantity of the window is [1, count_val].The col_name parameter starts to be supported after version 3.3.7.0. col_name specifies one or more columns. When counting in the count_window, for each row of data in the window, at least one of the specified columns must be non-null; otherwise, that row of data is not included in the counting window. If col_name is not specified, it means there is no non-null restriction.
128+
- EXTERNAL_WINDOW: External window. The time range of each window is explicitly defined by a subquery instead of being generated by built-in rules. The first two columns of the subquery must be of timestamp type, representing the window start and end times. Columns from the third column onward become window attribute columns and can be referenced through `window_alias.column_name`. The outer query calculates aggregate results independently within each window. It supports PARTITION BY alignment, HAVING filtering, nested usage, and more. For details, see [TDengine Distinctive Queries](24-distinguished.md#external-window).
127129
- interp_clause: Interp clause, used in conjunction with the interp function, specifying the recorded value or interpolation of the time section, can specify the time range of interpolation, output time interval, and interpolation type.
128130
- RANGE: Specify a single or start end time value, the end time must be greater than the start time. ts_val is a standard timestamp type. Such as ```RANGE('2023-10-01T00:00:00.000')``` or ```RANGE('2023-10-01T00:00:00.000', '2023-10-01T23:59:59.999')```.
129131
- EVERY: Time interval range, with every_val being a positive value and precision options of 1n, 1u, 1a, 1s, 1m, 1h, 1d, and 1w, such as EVERY (1s).

0 commit comments

Comments
 (0)