85 lines
2.5 KiB
SQL
85 lines
2.5 KiB
SQL
-- Before/after price comparison for each datacenter opening event (year_opened >= 2019)
|
|
-- Includes natural gas price context for the same time windows
|
|
WITH dc_events AS (
|
|
SELECT
|
|
d.name AS dc_name,
|
|
d.capacity_mw,
|
|
d.year_opened,
|
|
r.code AS region_code,
|
|
r.name AS region_name,
|
|
make_timestamptz(d.year_opened, 1, 1, 0, 0, 0) AS event_date
|
|
FROM datacenters d
|
|
JOIN grid_regions r ON d.region_id = r.id
|
|
WHERE d.year_opened >= 2019
|
|
),
|
|
price_before AS (
|
|
SELECT
|
|
de.dc_name,
|
|
AVG(ep.price_mwh) AS avg_price_before
|
|
FROM dc_events de
|
|
JOIN grid_regions r ON r.code = de.region_code
|
|
JOIN electricity_prices ep ON ep.region_id = r.id
|
|
AND ep.timestamp >= de.event_date - INTERVAL '6 months'
|
|
AND ep.timestamp < de.event_date
|
|
GROUP BY de.dc_name
|
|
),
|
|
price_after AS (
|
|
SELECT
|
|
de.dc_name,
|
|
AVG(ep.price_mwh) AS avg_price_after
|
|
FROM dc_events de
|
|
JOIN grid_regions r ON r.code = de.region_code
|
|
JOIN electricity_prices ep ON ep.region_id = r.id
|
|
AND ep.timestamp >= de.event_date
|
|
AND ep.timestamp < de.event_date + INTERVAL '6 months'
|
|
GROUP BY de.dc_name
|
|
),
|
|
gas_before AS (
|
|
SELECT
|
|
de.dc_name,
|
|
AVG(cp.price) AS avg_gas_before
|
|
FROM dc_events de
|
|
JOIN commodity_prices cp ON cp.commodity = 'natural_gas'
|
|
AND cp.timestamp >= de.event_date - INTERVAL '6 months'
|
|
AND cp.timestamp < de.event_date
|
|
GROUP BY de.dc_name
|
|
),
|
|
gas_after AS (
|
|
SELECT
|
|
de.dc_name,
|
|
AVG(cp.price) AS avg_gas_after
|
|
FROM dc_events de
|
|
JOIN commodity_prices cp ON cp.commodity = 'natural_gas'
|
|
AND cp.timestamp >= de.event_date
|
|
AND cp.timestamp < de.event_date + INTERVAL '6 months'
|
|
GROUP BY de.dc_name
|
|
)
|
|
SELECT
|
|
de.dc_name,
|
|
de.capacity_mw,
|
|
de.year_opened,
|
|
de.region_code,
|
|
de.region_name,
|
|
pb.avg_price_before,
|
|
pa.avg_price_after,
|
|
CASE
|
|
WHEN pb.avg_price_before > 0
|
|
THEN ((pa.avg_price_after - pb.avg_price_before) / pb.avg_price_before * 100)
|
|
ELSE NULL
|
|
END AS pct_change,
|
|
gb.avg_gas_before,
|
|
ga.avg_gas_after,
|
|
CASE
|
|
WHEN gb.avg_gas_before > 0
|
|
THEN ((ga.avg_gas_after - gb.avg_gas_before) / gb.avg_gas_before * 100)
|
|
ELSE NULL
|
|
END AS gas_pct_change
|
|
FROM dc_events de
|
|
LEFT JOIN price_before pb ON pb.dc_name = de.dc_name
|
|
LEFT JOIN price_after pa ON pa.dc_name = de.dc_name
|
|
LEFT JOIN gas_before gb ON gb.dc_name = de.dc_name
|
|
LEFT JOIN gas_after ga ON ga.dc_name = de.dc_name
|
|
WHERE pb.avg_price_before IS NOT NULL
|
|
AND pa.avg_price_after IS NOT NULL
|
|
ORDER BY ABS(COALESCE(pa.avg_price_after - pb.avg_price_before, 0)) DESC
|