Try CrateDB Live: Explore Queries
- 1. Choose Scenario
- 2. Get Ready
- 3. Run CrateDB
- 4. Import Data
- 5. Explore Queries
- 6. More Queries
- 7. Connect
- 8. Next Steps
A. Generic Queries
A1. Ingest Check
Verify row count and date range after COPY FROM
SELECT
COUNT(*) AS total_readings,
COUNT(DISTINCT tags['device_id']) AS devices,
COUNT(DISTINCT tags['plant_id']) AS plants,
MIN("timestamp") AS earliest,
MAX("timestamp") AS latest
FROM
rtia.iot_data;
| total_readings | devices | plants | earliest | latest |
|----------------|---------|--------|---------------------------|---------------------------|
| 500000 | 84 | 5 | 2025-09-01T00:00:02.000Z | 2026-05-08T23:04:58.000Z |
A2. Status Distribution
How healthy is the fleet right now?
SELECT
tags['status'] AS status,
COUNT(*) AS readings,
ROUND(
COUNT(*) * 100.0 / SUM(
COUNT(*)
) OVER (),
1
) AS pct
FROM
rtia.iot_data
GROUP BY
tags['status']
ORDER BY
readings DESC;
| status | readings | pct |
|----------|----------|------|
| normal | 459030 | 91.8 |
| warning | 24871 | 5 |
| offline | 8299 | 1.7 |
| critical | 7800 | 1.6 |
A3. Fault Rate by Device Type
Which sensor category generates the most alerts?
SELECT
tags[ 'device_type' ] AS device_type,
COUNT(*) AS total,
COUNT(*) FILTER (
WHERE
tags['status'] = 'warning'
) AS warnings,
COUNT(*) FILTER (
WHERE
tags['status'] = 'critical'
) AS criticals,
ROUND(
AVG(fields['quality_score']),
1
) AS avg_quality
FROM
rtia.iot_data
GROUP BY
tags[ 'device_type' ]
ORDER BY
criticals DESC;
| device_type | total | warnings | criticals | avg_quality |
|--------------------|---------|----------|-----------|-------------|
| temperature_sensor | 170000 | 6890 | 5885 | 92.3 |
| power_meter | 102000 | 5014 | 982 | 92.7 |
| flow_meter | 60000 | 2745 | 827 | 92.7 |
| pressure_sensor | 60000 | 2943 | 106 | 92.8 |
| vibration_sensor | 108000 | 7279 | 0 | 92.9 |
A4. Time-series: Hourly Fault Trend
Critical events per hour — spot operational patterns
SELECT
DATE_TRUNC('hour', "timestamp") AS hour,
COUNT(*) FILTER (
WHERE
tags['status'] = 'critical'
) AS critical_count
FROM
rtia.iot_data
GROUP BY
hour
ORDER BY
hour;
| hour | critical_count |
|--------------------------|----------------|
| 2025-09-01T00:00:00.000Z | 0 |
| 2025-09-01T01:00:00.000Z | 0 |
| 2025-09-01T02:00:00.000Z | 0 |
| 2025-09-01T03:00:00.000Z | 0 |
| 2025-09-01T04:00:00.000Z | 0 |
| 2025-09-01T05:00:00.000Z | 0 |
| 2025-09-01T06:00:00.000Z | 0 |
A5. GEO: Alert Density Per Plant
Where on the map are faults clustering?
SELECT
tags['plant_id'] AS plant_id,
ANY_VALUE(geo_location) AS location,
COUNT(*) FILTER (
WHERE
tags['status'] = 'critical'
) AS critical_readings,
ROUND(
AVG(fields['quality_score']),
1
) AS avg_quality
FROM
rtia.iot_data
GROUP BY
tags['plant_id']
ORDER BY
critical_readings DESC;
| plant_id | location | critical_readings | avg_quality |
|------------------|---------------------------------------------|-------------------|-------------|
| PLANT_DORTMUND | [7.4867, 51.4742] | 2456 | 92.4 |
| PLANT_STUTTGART | [9.1414, 48.7937] | 1695 | 92.3 |
| PLANT_HAMBURG | [9.9533, 53.5976] | 1684 | 92.6 |
| PLANT_MUNICH | [11.5494, 48.1141] | 1014 | 93 |
| PLANT_LEIPZIG | [12.3436, 51.3093] | 951 | 92.9 |
A6. JOIN: Fault Rate By Industry Segment
iot_data + plants → which industry has the worst quality?
SELECT
p.industry_segment,
p.plant_name,
p.employee_count,
COUNT(*) FILTER (
WHERE
i.tags['status'] = 'critical'
) AS critical_events,
COUNT(*) FILTER (
WHERE
i.tags['status'] = 'warning'
) AS warning_events,
ROUND(
AVG(i.fields['quality_score']),
1
) AS avg_quality
FROM
rtia.iot_data i
JOIN rtia.plants p ON i.tags['plant_id'] = p.plant_id
GROUP BY
p.industry_segment,
p.plant_name,
p.employee_count
ORDER BY
critical_events DESC;
| industry_segment | plant_name | employee_count | critical_events | warning_events | avg_quality |
|------------------|---------------------------------|----------------|-----------------|----------------|-------------|
| Steel & Metals | Dortmund Steel Processing | 980 | 2456 | 5105 | 92.4 |
| Automotive | Stuttgart Automotive Assembly | 1240 | 1695 | 7153 | 92.3 |
| Chemicals | Hamburg Chemical Processing | 650 | 1684 | 4643 | 92.6 |
| Electronics | Munich Electronics Manufacturing| 870 | 1014 | 4117 | 93 |
| Logistics | Leipzig Logistics Center | 430 | 951 | 3853 | 92.9
A7. JOIN: Critical Alerts On Out-of-warranty Assets
iot_data + devices → find exposed assets that need budget attention
SELECT
d.device_id,
d.manufacturer,
d.device_type,
d.warranty_expiry,
d.asset_value_eur,
COUNT(*) AS critical_readings,
MAX(i."timestamp") AS last_critical_at
FROM
rtia.iot_data i
JOIN rtia.devices d ON i.tags['device_id'] = d.device_id
WHERE
i.tags['status'] = 'critical'
AND d.warranty_expiry < TIMESTAMP '2025-09-01'
GROUP BY
d.device_id,
d.manufacturer,
d.device_type,
d.warranty_expiry,
d.asset_value_eur
ORDER BY
critical_readings DESC
LIMIT
15;
| device_id | manufacturer | device_type | warranty_expiry | asset_value_eur | critical_readings | last_critical_at |
|-------------|-----------------|--------------------|---------------------------|-----------------|-------------------|---------------------------|
| DEVICE_0046 | Siemens | temperature_sensor | 2023-12-07T00:00:00.000Z | 1704.53 | 1503 | 2026-03-10T19:01:22.000Z |
| DEVICE_0009 | Siemens | temperature_sensor | 2025-04-18T00:00:00.000Z | 1739.62 | 1174 | 2026-01-30T04:04:30.000Z |
| DEVICE_0035 | Phoenix Contact | power_meter | 2022-09-13T00:00:00.000Z | 2612.77 | 909 | 2026-02-21T07:04:40.000Z |
| DEVICE_0028 | Siemens | flow_meter | 2024-10-30T00:00:00.000Z | 5466.47 | 776 | 2026-02-22T01:01:37.000Z |
| DEVICE_0033 | ifm electronic | temperature_sensor | 2022-11-02T00:00:00.000Z | 875.72 | 738 | 2026-04-24T21:03:28.000Z |
| DEVICE_0026 | Bürkert | pressure_sensor | 2025-05-04T00:00:00.000Z | 1467.68 | 106 | 2026-03-01T12:04:55.000Z |
| DEVICE_0018 | WIKA | temperature_sensor | 2025-04-07T00:00:00.000Z | 909.97 | 88 | 2025-10-05T06:00:13.000Z |
| DEVICE_0031 | WIKA | temperature_sensor | 2023-05-27T00:00:00.000Z | 1120.01 | 86 | 2026-01-23T02:02:26.000Z |
| DEVICE_0073 | Bürkert | flow_meter | 2025-06-30T00:00:00.000Z | 5312.31 | 51 | 2025-12-18T07:02:07.000Z |
| DEVICE_0020 | Phoenix Contact | power_meter | 2024-11-03T00:00:00.000Z | 2472.92 | 42 | 2026-01-20T01:00:55.000Z |
| DEVICE_0038 | ABB | power_meter | 2024-05-06T00:00:00.000Z | 3847.75 | 31 | 2025-09-16T02:04:21.000Z |
A8. JOIN: Overdue Maintenance
iot_data + devices → devices past their scheduled service date and still active
SELECT
d.device_id,
d.device_type,
d.plant_id,
d.responsible_technician,
d.next_maintenance_due,
COUNT(*) FILTER (
WHERE
i.tags['status'] IN ('warning', 'critical')
) AS fault_readings
FROM
rtia.iot_data i
JOIN rtia.devices d ON i.tags['device_id'] = d.device_id
WHERE
d.next_maintenance_due < TIMESTAMP '2025-09-01'
GROUP BY
d.device_id,
d.device_type,
d.plant_id,
d.responsible_technician,
d.next_maintenance_due
ORDER BY
fault_readings DESC
LIMIT
15;
|-------------|--------------------|-----------------|------------------------|---------------------------|----------------|
| DEVICE_0046 | temperature_sensor | PLANT_STUTTGART | J. Koch | 2025-07-15T00:00:00.000Z | 2250 |
| DEVICE_0006 | vibration_sensor | PLANT_STUTTGART | P. Wagner | 2025-08-28T00:00:00.000Z | 1820 |
| DEVICE_0066 | vibration_sensor | PLANT_STUTTGART | S. Neumann | 2025-04-28T00:00:00.000Z | 1456 |
| DEVICE_0028 | flow_meter | PLANT_HAMBURG | P. Wagner | 2025-04-29T00:00:00.000Z | 1163 |
| DEVICE_0031 | temperature_sensor | PLANT_STUTTGART | M. Fischer | 2025-04-10T00:00:00.000Z | 1000 |
| DEVICE_0012 | power_meter | PLANT_MUNICH | W. Klein | 2025-05-20T00:00:00.000Z | 932 |
| DEVICE_0020 | power_meter | PLANT_LEIPZIG | M. Fischer | 2025-04-14T00:00:00.000Z | 894 |
| DEVICE_0018 | temperature_sensor | PLANT_HAMBURG | A. Schmidt | 2025-04-19T00:00:00.000Z | 799 |
| DEVICE_0073 | flow_meter | PLANT_HAMBURG | H. Müller | 2025-07-25T00:00:00.000Z | 711 |
| DEVICE_0059 | pressure_sensor | PLANT_DORTMUND | E. Braun | 2025-05-31T00:00:00.000Z | 668 |
| DEVICE_0055 | flow_meter | PLANT_LEIPZIG | W. Klein | 2025-05-06T00:00:00.000Z | 659 |
| DEVICE_0010 | flow_meter | PLANT_LEIPZIG | P. Wagner | 2025-06-07T00:00:00.000Z | 481 |
| DEVICE_0081 | vibration_sensor | PLANT_STUTTGART | H. Müller | 2025-05-30T00:00:00.000Z | 466 |
| DEVICE_0045 | temperature_sensor | PLANT_LEIPZIG | H. Müller | 2025-05-26T00:00:00.000Z | 0 |
| DEVICE_0079 | vibration_sensor | PLANT_DORTMUND | S. Neumann | 2025-08-27T00:00:00.000Z | 0 |
A9. JOIN: Devices Still Faulting After Maintenance
iot_data + devices + maintenance_log → maintenance that did not hold
SELECT
i.tags['device_id'] AS device_id,
d.manufacturer,
d.device_type,
m.maintenance_type,
m.completed_date,
m.cost_eur,
COUNT(*) AS fault_readings_after_service
FROM
rtia.iot_data i
JOIN rtia.devices d ON i.tags['device_id'] = d.device_id
JOIN rtia.maintenance_log m ON i.tags['device_id'] = m.device_id
WHERE
i.tags['status'] IN ('warning', 'critical')
AND m.status = 'completed'
AND i."timestamp" > m.completed_date :: TIMESTAMP
GROUP BY
i.tags['device_id'],
d.manufacturer,
d.device_type,
m.maintenance_type,
m.completed_date,
m.cost_eur
ORDER BY
fault_readings_after_service DESC
LIMIT
10;
| device_id | manufacturer | device_type | maintenance_type | completed_date | cost_eur | fault_readings_after_service |
|-------------|-----------------|--------------------|------------------|---------------------------|----------|------------------------------|
| DEVICE_0046 | Siemens | temperature_sensor | preventive | 2023-03-25T00:00:00.000Z | 795.06 | 2250 |
| DEVICE_0046 | Siemens | temperature_sensor | preventive | 2023-04-11T00:00:00.000Z | 566.72 | 2250 |
| DEVICE_0046 | Siemens | temperature_sensor | preventive | 2022-10-04T00:00:00.000Z | 1285.88 | 2250 |
| DEVICE_0046 | Siemens | temperature_sensor | preventive | 2022-12-05T00:00:00.000Z | 522.79 | 2250 |
| DEVICE_0009 | Siemens | temperature_sensor | preventive | 2023-01-29T00:00:00.000Z | 877.72 | 1870 |
| DEVICE_0009 | Siemens | temperature_sensor | preventive | 2025-07-05T00:00:00.000Z | 781.76 | 1870 |
| DEVICE_0009 | Siemens | temperature_sensor | preventive | 2025-05-14T00:00:00.000Z | 776.58 | 1870 |
| DEVICE_0069 | Endress+Hauser | temperature_sensor | preventive | 2025-03-10T00:00:00.000Z | 1040.68 | 1843 |
| DEVICE_0069 | Endress+Hauser | temperature_sensor | corrective | 2025-05-14T00:00:00.000Z | 3961.36 | 1843 |
| DEVICE_0069 | Endress+Hauser | temperature_sensor | preventive | 2024-03-18T00:00:00.000Z | 573.91 | 1843 |
A10. Aggregated Maintenance Cost By Plant
maintenance_log + plants → operational spend overview
SELECT
p.plant_name,
p.industry_segment,
COUNT(m.work_order_id) AS work_orders,
COUNT(*) FILTER (
WHERE
m.maintenance_type = 'emergency'
) AS emergency_jobs,
ROUND(
SUM(m.cost_eur),
0
) AS total_cost_eur,
ROUND(
AVG(m.cost_eur),
0
) AS avg_cost_per_job
FROM
rtia.maintenance_log m
JOIN rtia.plants p ON m.plant_id = p.plant_id
WHERE
m.status = 'completed'
GROUP BY
p.plant_name,
p.industry_segment
ORDER BY
total_cost_eur DESC;
| plant_name | industry_segment | work_orders | emergency_jobs | total_cost_eur | avg_cost_per_job |
|---------------------------------|------------------|-------------|----------------|----------------|------------------|
| Hamburg Chemical Processing | Chemicals | 364 | 40 | 645713 | 1774 |
| Dortmund Steel Processing | Steel & Metals | 353 | 37 | 624559 | 1769 |
| Leipzig Logistics Center | Logistics | 332 | 37 | 589389 | 1775 |
| Stuttgart Automotive Assembly | Automotive | 346 | 32 | 566962 | 1639 |
| Munich Electronics Manufacturing| Electronics | 349 | 27 | 562267 | 1611 |
A11. Object Field Access: Fault Rate By Firmware Version
Demonstrates bracket notation on the metadata OBJECT column. Telegraf flattens the per-device metadata into tags['metadata_*'] (it can only carry flat strings), so the firmware/model dimensions live there. Surfaces whether a specific firmware release correlates with higher fault rates.
SELECT
tags['metadata_firmware_version'] AS firmware_version,
tags['metadata_model'] AS model,
COUNT(*) AS total_readings,
COUNT(*) FILTER (
WHERE
tags['status'] = 'critical'
) AS critical_count,
COUNT(*) FILTER (
WHERE
tags['status'] = 'warning'
) AS warning_count,
ROUND(
AVG(fields['quality_score']),
1
) AS avg_quality
FROM
rtia.iot_data
GROUP BY
tags['metadata_firmware_version'],
tags['metadata_model']
ORDER BY
critical_count DESC
LIMIT
20;
| firmware_version | model | total_readings | critical_count | warning_count | avg_quality |
|------------------|--------|----------------|----------------|---------------|-------------|
| 2.0.5 | SX-282 | 6000 | 1503 | 747 | 86.1 |
| 2.0.1 | SX-197 | 6000 | 1282 | 561 | 87.7 |
| 3.8.8 | SX-404 | 6000 | 1174 | 696 | 87.7 |
| 2.8.3 | SX-244 | 6000 | 1014 | 505 | 89 |
| 2.1.2 | SX-206 | 6000 | 909 | 455 | 89.5 |
| 3.2.2 | SX-218 | 6000 | 776 | 387 | 90.3 |
| 3.5.4 | SX-216 | 6000 | 738 | 370 | 90.3 |
| 2.2.1 | SX-262 | 6000 | 106 | 913 | 90.6 |
| 2.8.7 | SX-102 | 6000 | 88 | 711 | 91.5 |
| 2.3.1 | SX-417 | 6000 | 86 | 914 | 91.1 |
A12. DATE_BIN: Fixed-width 15-Minute Time Windows
DATE_BIN buckets readings into precise fixed-width intervals. Useful for shift reporting and SLA windows.
SELECT
DATE_BIN(
'15 minutes' :: INTERVAL, "timestamp",
TIMESTAMP '2025-09-01'
) AS window_start,
tags['device_type'] AS device_type,
COUNT(*) AS readings,
COUNT(*) FILTER (
WHERE
tags['status'] = 'critical'
) AS criticals,
ROUND(
AVG(fields['metric_value']),
2
) AS avg_value
FROM
rtia.iot_data
WHERE
"timestamp" >= TIMESTAMP '2025-09-01 06:00:00'
AND "timestamp" < TIMESTAMP '2025-09-01 14:00:00'
GROUP BY
window_start,
tags['device_type']
ORDER BY
window_start,
device_type;
| window_start | device_type | readings | criticals | avg_value |
|---------------------------|--------------------|----------|-----------|-----------|
| 2025-09-01T06:00:00.000Z | flow_meter | 10 | 0 | 168.97 |
| 2025-09-01T06:00:00.000Z | power_meter | 17 | 0 | 329.44 |
| 2025-09-01T06:00:00.000Z | pressure_sensor | 10 | 0 | 3.7 |
| 2025-09-01T06:00:00.000Z | temperature_sensor | 29 | 0 | 61.04 |
| 2025-09-01T06:00:00.000Z | vibration_sensor | 18 | 0 | 1.57 |
| 2025-09-01T07:00:00.000Z | flow_meter | 10 | 0 | 180.2 |
| 2025-09-01T07:00:00.000Z | power_meter | 17 | 0 | 334.6 |
| 2025-09-01T07:00:00.000Z | pressure_sensor | 10 | 0 | 3.77 |
| 2025-09-01T07:00:00.000Z | temperature_sensor | 29 | 0 | 60.91 |
| 2025-09-01T07:00:00.000Z | vibration_sensor | 18 | 0 | 1.72 |
| 2025-09-01T08:00:00.000Z | flow_meter | 10 | 0 | 163.85 |
| 2025-09-01T08:00:00.000Z | power_meter | 17 | 0 | 329.39 |
| 2025-09-01T08:00:00.000Z | pressure_sensor | 10 | 0 | 3.62 |
| 2025-09-01T08:00:00.000Z | temperature_sensor | 29 | 0 | 60.79 |
| 2025-09-01T08:00:00.000Z | vibration_sensor | 18 | 0 | 1.52 |
A13. OEE Approximation By Plant And Device Type
Overall Equipment Effectiveness derived from sensor status and quality_score. This is an approximation, a full OEE calculation requires a shift_production table with runtime, planned time, actual output, and good units. Using the fields available in iiot.iot_data:
- Availability = share of readings where device was online (status != 'offline')
- Performance = share of online readings in normal operating state
- Quality = average quality_score of online readings, normalised to 0–1
- OEE = Availability × Performance × Quality × 100
SELECT
i.tags['plant_id'] AS plant_id,
p.plant_name,
p.industry_segment,
i.tags['device_type'] AS device_type,
COUNT(*) AS total_readings,
ROUND(
COUNT(*) FILTER (
WHERE
i.tags['status'] != 'offline'
) * 100.0 / NULLIF(
COUNT(*),
0
),
1
) AS availability_pct,
ROUND(
COUNT(*) FILTER (
WHERE
i.tags['status'] = 'normal'
) * 100.0 / NULLIF(
COUNT(*) FILTER (
WHERE
i.tags['status'] != 'offline'
),
0
),
1
) AS performance_pct,
ROUND(
AVG(i.fields['quality_score']) FILTER (
WHERE
i.tags['status'] != 'offline'
),
1
) AS quality_score_avg,
ROUND(
(
COUNT(*) FILTER (
WHERE
i.tags['status'] != 'offline'
) * 1.0 / NULLIF(
COUNT(*),
0
)
) * (
COUNT(*) FILTER (
WHERE
i.tags['status'] = 'normal'
) * 1.0 / NULLIF(
COUNT(*) FILTER (
WHERE
i.tags['status'] != 'offline'
),
0
)
) * (
AVG(i.fields['quality_score']) FILTER (
WHERE
i.tags['status'] != 'offline'
) / 100.0
) * 100,
1
) AS oee_approx_pct
FROM
rtia.iot_data i
JOIN rtia.plants p ON i.tags['plant_id'] = p.plant_id
GROUP BY
i.tags['plant_id'],
p.plant_name,
p.industry_segment,
i.tags['device_type']
ORDER BY
oee_approx_pct ASC;
|-----------------|----------------------------------|------------------|--------------------|----------------|------------------|-----------------|-------------------|----------------|
| PLANT_DORTMUND | Dortmund Steel Processing | Steel & Metals | temperature_sensor | 32000 | 98.6 | 86.6 | 92.1 | 78.7 |
| PLANT_STUTTGART | Stuttgart Automotive Assembly | Automotive | vibration_sensor | 36000 | 98.6 | 88.6 | 93.6 | 81.7 |
| PLANT_STUTTGART | Stuttgart Automotive Assembly | Automotive | temperature_sensor | 36000 | 98.3 | 90.8 | 93.2 | 83.1 |
| PLANT_HAMBURG | Hamburg Chemical Processing | Chemicals | flow_meter | 30000 | 98.3 | 91.8 | 93.6 | 84.4 |
| PLANT_LEIPZIG | Leipzig Logistics Center | Logistics | power_meter | 36000 | 98.2 | 92.5 | 93.6 | 85.1 |
| PLANT_MUNICH | Munich Electronics Manufacturing | Electronics | temperature_sensor | 36000 | 98.5 | 93.3 | 93.7 | 86.2 |
| PLANT_HAMBURG | Hamburg Chemical Processing | Chemicals | temperature_sensor | 36000 | 98.3 | 94.6 | 94 | 87.4 |
| PLANT_STUTTGART | Stuttgart Automotive Assembly | Automotive | pressure_sensor | 30000 | 97.9 | 94.7 | 94.3 | 87.4 |
| PLANT_HAMBURG | Hamburg Chemical Processing | Chemicals | power_meter | 36000 | 98.3 | 94.4 | 94.3 | 87.5 |
| PLANT_DORTMUND | Dortmund Steel Processing | Steel & Metals | vibration_sensor | 36000 | 98.2 | 94.8 | 94.4 | 87.9 |
| PLANT_DORTMUND | Dortmund Steel Processing | Steel & Metals | pressure_sensor | 30000 | 98.3 | 94.9 | 94.3 | 88.1 |
| PLANT_MUNICH | Munich Electronics Manufacturing | Electronics | power_meter | 30000 | 98.3 | 95.4 | 94.4 | 88.5 |
| PLANT_MUNICH | Munich Electronics Manufacturing | Electronics | vibration_sensor | 36000 | 98.4 | 96 | 94.5 | 89.3 |
| PLANT_LEIPZIG | Leipzig Logistics Center | Logistics | flow_meter | 30000 | 98.4 | 96.1 | 94.5 | 89.4 |
| PLANT_LEIPZIG | Leipzig Logistics Center | Logistics | temperature_sensor | 30000 | 98.4 | 96.6 | 94.6 | 89.9 |