Language
WITH Scripts and Multiple Outputs
ChronusQL scripts can define intermediate named scopes with `WITH`, then write one or more final outputs.
Guide
ChronusQL scripts can define intermediate named scopes with `WITH`, then write one or more final outputs.
sql
WITH NormalReadings AS
(
SELECT ts, SensorId, Reading
FROM Sensor
WHERE Reading < 100 AND Reading > 0
),
Averages AS
(
SELECT SensorId, AVG(Reading) AS AvgNormalReading
FROM NormalReadings TIMESTAMP BY ts
GROUP BY SensorId, TumblingWindow(Duration(minute, 1))
HAVING AVG(Reading) > 10
)
SELECT * INTO outputAlerts FROM Averages;
SELECT * INTO outputLog FROM NormalReadings;Tested input:
jsonl
{"ts":638712864010000000,"SensorId":"A","Reading":20}
{"ts":638712864100000000,"SensorId":"A","Reading":20}
{"ts":638712864200000000,"SensorId":"B","Reading":5}
{"ts":638712864300000000,"SensorId":"B","Reading":150}Tested `outputAlerts`:
jsonl
{"SensorId":"A","AvgNormalReading":20}Tested `outputLog`:
jsonl
{"ts":638712864010000000,"SensorId":"A","Reading":20}
{"ts":638712864100000000,"SensorId":"A","Reading":20}
{"ts":638712864200000000,"SensorId":"B","Reading":5}The `Reading` value `150` is removed by `NormalReadings`, so it appears in neither downstream output.
WITH Grammar
text
WITH <scope-name> AS
(
<select-query-without-final-output-semantics>
)
[, <scope-name> AS (...)]
<output-select-statement>;
[<output-select-statement>;]Tested `WITH` scopes can contain:
- Plain `SELECT`.
- `WHERE`.
- `TIMESTAMP BY`.
- `GROUP BY TumblingWindow(...)`.
- `HAVING`.
- `WINDOW BY ... COMPUTE`.
- `MATCH_RECOGNIZE`.
Single-query parsing rejects `WITH`; scripts must be parsed/executed as scripts.
WITH, Windowing, and Pattern Matching Together
The tests include a multi-output script that filters clean events, produces window counts, produces pattern matches, and writes the clean log.
sql
WITH Clean AS
(
SELECT ts, run_id, SensorId, kind, Reading
FROM input
WHERE Reading > 0
),
Windowed AS
(
SELECT SensorId, Window.EndTime AS WindowEnd, COUNT(*) AS EventCount
FROM Clean TIMESTAMP BY ts
GROUP BY SensorId, TumblingWindow(Duration(second, 8))
HAVING COUNT(*) >= 4
),
Matched AS
(
SELECT mr.run_id, mr.SensorId, mr.start_reading, mr.end_reading
FROM Clean TIMESTAMP BY ts
MATCH_RECOGNIZE (
PARTITION BY run_id
LIMIT Duration(second, 10)
MEASURES
A.run_id AS run_id,
A.SensorId AS SensorId,
A.Reading AS start_reading,
LAST(B.Reading) AS end_reading
ONE ROW PER MATCH
AFTER MATCH SKIP TO NEXT ROW
PATTERN (A B+)
DEFINE
A AS A.kind = 'A',
B AS B.kind = 'B' AND B.Reading > PREV(B.Reading)
) AS mr
)
SELECT * INTO outputWindow FROM Windowed;
SELECT * INTO outputMatch FROM Matched;
SELECT * INTO outputLog FROM Clean;