-- Migrated from DuckDB test: test/sql/join/ join with aggregate tests
-- Tests joins combined with aggregate functions
CREATE TABLE sensors(sensor_id INTEGER, sensor_name VARCHAR, "location" VARCHAR, ts TIMESTAMP TIME INDEX);

Affected Rows: 0

CREATE TABLE readings(reading_id INTEGER, sensor_id INTEGER, "value" DOUBLE, reading_time TIMESTAMP, ts TIMESTAMP TIME INDEX);

Affected Rows: 0

INSERT INTO sensors VALUES
(1, 'TempSensor1', 'Room A', 1000), (2, 'TempSensor2', 'Room B', 2000),
(3, 'HumiditySensor1', 'Room A', 3000), (4, 'HumiditySensor2', 'Room B', 4000);

Affected Rows: 4

INSERT INTO readings VALUES
(1, 1, 22.5, '2023-01-01 10:00:00', 1000), (2, 1, 23.1, '2023-01-01 11:00:00', 2000),
(3, 1, 21.8, '2023-01-01 12:00:00', 3000), (4, 2, 25.3, '2023-01-01 10:00:00', 4000),
(5, 2, 26.0, '2023-01-01 11:00:00', 5000), (6, 2, 24.7, '2023-01-01 12:00:00', 6000),
(7, 3, 45.2, '2023-01-01 10:00:00', 7000), (8, 3, 46.8, '2023-01-01 11:00:00', 8000),
(9, 4, 52.1, '2023-01-01 10:00:00', 9000), (10, 4, 51.3, '2023-01-01 11:00:00', 10000);

Affected Rows: 10

-- Join with basic aggregation
SELECT
  s.sensor_name, s."location",
  COUNT(r.reading_id) as reading_count,
  AVG(r."value") as avg_value,
  MIN(r."value") as min_value,
  MAX(r."value") as max_value
FROM sensors s
INNER JOIN readings r ON s.sensor_id = r.sensor_id
GROUP BY s.sensor_id, s.sensor_name, s."location"
ORDER BY s.sensor_name;

+-----------------+----------+---------------+--------------------+-----------+-----------+
| sensor_name     | location | reading_count | avg_value          | min_value | max_value |
+-----------------+----------+---------------+--------------------+-----------+-----------+
| HumiditySensor1 | Room A   | 2             | 46.0               | 45.2      | 46.8      |
| HumiditySensor2 | Room B   | 2             | 51.7               | 51.3      | 52.1      |
| TempSensor1     | Room A   | 3             | 22.46666666666667  | 21.8      | 23.1      |
| TempSensor2     | Room B   | 3             | 25.333333333333332 | 24.7      | 26.0      |
+-----------------+----------+---------------+--------------------+-----------+-----------+

-- Join with time-based aggregation
SELECT
  s."location",
  DATE_TRUNC('hour', r.reading_time) as hour_bucket,
  COUNT(*) as readings_per_hour,
  AVG(r."value") as avg_hourly_value
FROM sensors s
INNER JOIN readings r ON s.sensor_id = r.sensor_id
GROUP BY s."location", DATE_TRUNC('hour', r.reading_time)
ORDER BY s."location", hour_bucket;

+----------+---------------------+-------------------+------------------+
| location | hour_bucket         | readings_per_hour | avg_hourly_value |
+----------+---------------------+-------------------+------------------+
| Room A   | 2023-01-01T10:00:00 | 2                 | 33.85            |
| Room A   | 2023-01-01T11:00:00 | 2                 | 34.95            |
| Room A   | 2023-01-01T12:00:00 | 1                 | 21.8             |
| Room B   | 2023-01-01T10:00:00 | 2                 | 38.7             |
| Room B   | 2023-01-01T11:00:00 | 2                 | 38.65            |
| Room B   | 2023-01-01T12:00:00 | 1                 | 24.7             |
+----------+---------------------+-------------------+------------------+

-- Aggregation before join
SELECT
  s.sensor_name, s."location", agg_readings.avg_value, agg_readings.reading_count
FROM sensors s
INNER JOIN (
  SELECT sensor_id, AVG("value") as avg_value, COUNT(*) as reading_count
  FROM readings
  GROUP BY sensor_id
) agg_readings ON s.sensor_id = agg_readings.sensor_id
WHERE agg_readings.avg_value > 30.0
ORDER BY agg_readings.avg_value DESC;

+-----------------+----------+-----------+---------------+
| sensor_name     | location | avg_value | reading_count |
+-----------------+----------+-----------+---------------+
| HumiditySensor2 | Room B   | 51.7      | 2             |
| HumiditySensor1 | Room A   | 46.0      | 2             |
+-----------------+----------+-----------+---------------+

-- Multiple aggregation levels with joins
SELECT
  location_summary.location,
  location_summary.sensor_count,
  location_summary.avg_readings_per_sensor,
  location_summary.location_avg_value
FROM (
  SELECT
    s."location",
    COUNT(DISTINCT s.sensor_id) as sensor_count,
    COUNT(r.reading_id) / COUNT(DISTINCT s.sensor_id) as avg_readings_per_sensor,
    ROUND(AVG(r."value"), 6) as location_avg_value
  FROM sensors s
  INNER JOIN readings r ON s.sensor_id = r.sensor_id
  GROUP BY s."location"
) location_summary
ORDER BY location_summary.location_avg_value DESC;

+----------+--------------+-------------------------+--------------------+
| location | sensor_count | avg_readings_per_sensor | location_avg_value |
+----------+--------------+-------------------------+--------------------+
| Room B   | 2            | 2                       | 35.88              |
| Room A   | 2            | 2                       | 31.88              |
+----------+--------------+-------------------------+--------------------+

-- Join with aggregated conditions
SELECT
  s.sensor_name,
  high_readings.high_count,
  high_readings.avg_high_value
FROM sensors s
INNER JOIN (
  SELECT
    sensor_id,
    COUNT(*) as high_count,
    AVG("value") as avg_high_value
  FROM readings
  WHERE "value" > 25.0
  GROUP BY sensor_id
  HAVING COUNT(*) >= 2
) high_readings ON s.sensor_id = high_readings.sensor_id
ORDER BY high_readings.avg_high_value DESC;

+-----------------+------------+----------------+
| sensor_name     | high_count | avg_high_value |
+-----------------+------------+----------------+
| HumiditySensor2 | 2          | 51.7           |
| HumiditySensor1 | 2          | 46.0           |
| TempSensor2     | 2          | 25.65          |
+-----------------+------------+----------------+

DROP TABLE sensors;

Affected Rows: 0

DROP TABLE readings;

Affected Rows: 0

