实用SQL查询集合(用于Metabase BI监控)

以下是一系列可直接添加到您的Metabase BI平台的SQL查询,用于长期监控设备健康状况。这些查询基于您的TimescaleDB数据仓库设计,并针对不同的监控需求进行了优化。

1. 设备健康概览仪表板

1.1 设备电气参数偏离正常范围统计

-- 设备电气参数异常统计(过去24小时)
WITH parameter_limits AS (
    SELECT 
        'UA_Voltage' AS param, 5.79 AS lower_limit, 6.10 AS upper_limit
    UNION ALL
    SELECT 'UB_Voltage', 5.70, 5.94
    UNION ALL
    SELECT 'UC_Voltage', 5.75, 5.99
    UNION ALL
    SELECT 'UAB_Voltage', 9.78, 10.19
    UNION ALL
    SELECT 'UBC_Voltage', 9.77, 10.17
    UNION ALL
    SELECT 'IA_Current', 6.62, 19.23
    UNION ALL
    SELECT 'IB_Current', 5.51, 16.95
    UNION ALL
    SELECT 'Power_COS', 0.68, 1.0
),
abnormal_readings AS (
    SELECT
        f.ftukey,
        dt.hour,
        CASE 
            WHEN f.ua_voltage < (SELECT lower_limit FROM parameter_limits WHERE param = 'UA_Voltage') 
               OR f.ua_voltage > (SELECT upper_limit FROM parameter_limits WHERE param = 'UA_Voltage')
               THEN 1 ELSE 0 
        END AS ua_abnormal,
        CASE 
            WHEN f.ub_voltage < (SELECT lower_limit FROM parameter_limits WHERE param = 'UB_Voltage') 
               OR f.ub_voltage > (SELECT upper_limit FROM parameter_limits WHERE param = 'UB_Voltage')
               THEN 1 ELSE 0 
        END AS ub_abnormal,
        CASE 
            WHEN f.uc_voltage < (SELECT lower_limit FROM parameter_limits WHERE param = 'UC_Voltage') 
               OR f.uc_voltage > (SELECT upper_limit FROM parameter_limits WHERE param = 'UC_Voltage')
               THEN 1 ELSE 0 
        END AS uc_abnormal,
        CASE 
            WHEN f.uab_voltage < (SELECT lower_limit FROM parameter_limits WHERE param = 'UAB_Voltage') 
               OR f.uab_voltage > (SELECT upper_limit FROM parameter_limits WHERE param = 'UAB_Voltage')
               THEN 1 ELSE 0 
        END AS uab_abnormal,
        CASE 
            WHEN f.ubc_voltage < (SELECT lower_limit FROM parameter_limits WHERE param = 'UBC_Voltage') 
               OR f.ubc_voltage > (SELECT upper_limit FROM parameter_limits WHERE param = 'UBC_Voltage')
               THEN 1 ELSE 0 
        END AS ubc_abnormal,
        CASE 
            WHEN f.ia_current < (SELECT lower_limit FROM parameter_limits WHERE param = 'IA_Current') 
               OR f.ia_current > (SELECT upper_limit FROM parameter_limits WHERE param = 'IA_Current')
               THEN 1 ELSE 0 
        END AS ia_abnormal,
        CASE 
            WHEN f.ib_current < (SELECT lower_limit FROM parameter_limits WHERE param = 'IB_Current') 
               OR f.ib_current > (SELECT upper_limit FROM parameter_limits WHERE param = 'IB_Current')
               THEN 1 ELSE 0 
        END AS ib_abnormal,
        CASE 
            WHEN f.power_cos < (SELECT lower_limit FROM parameter_limits WHERE param = 'Power_COS') 
               OR f.power_cos > (SELECT upper_limit FROM parameter_limits WHERE param = 'Power_COS')
               THEN 1 ELSE 0 
        END AS cos_abnormal
    FROM factpowerreadings f
    JOIN dimtime dt ON f.timestampkey = dt.timestampkey
    WHERE f.readingtimestamp >= NOW() - INTERVAL '24 hours'
)
SELECT 
    ftukey AS "设备ID",
    COUNT(*) AS "总读数",
    SUM(ua_abnormal) AS "UA电压异常次数",
    SUM(ub_abnormal) AS "UB电压异常次数",
    SUM(uc_abnormal) AS "UC电压异常次数",
    SUM(uab_abnormal) AS "UAB线电压异常次数",
    SUM(ubc_abnormal) AS "UBC线电压异常次数",
    SUM(ia_abnormal) AS "A相电流异常次数",
    SUM(ib_abnormal) AS "B相电流异常次数",
    SUM(cos_abnormal) AS "功率因数异常次数",
    ROUND(100.0 * (SUM(ua_abnormal) + SUM(ub_abnormal) + SUM(uc_abnormal) + 
           SUM(uab_abnormal) + SUM(ubc_abnormal) + SUM(ia_abnormal) + 
           SUM(ib_abnormal) + SUM(cos_abnormal)) / 
           (COUNT(*) * 8), 2) AS "参数异常率(%)"
FROM abnormal_readings
GROUP BY ftukey
ORDER BY "参数异常率(%)" DESC;

1.2 三相不平衡趋势监控

-- 三相不平衡度趋势(按小时聚合)
WITH hourly_data AS (
    SELECT 
        f.ftukey,
        time_bucket('1 hour', f.readingtimestamp) AS hour_bucket,
        AVG(f.ia_current) AS avg_ia,
        AVG(f.ib_current) AS avg_ib,
        AVG(f.ic_current) AS avg_ic,
        AVG(f.ua_voltage) AS avg_ua,
        AVG(f.ub_voltage) AS avg_ub,
        AVG(f.uc_voltage) AS avg_uc
    FROM factpowerreadings f
    WHERE 
        f.readingtimestamp >= NOW() - INTERVAL '7 days'
        AND f.ia_current > 0 AND f.ib_current > 0 AND f.ic_current > 0 
        AND f.ua_voltage > 0 AND f.ub_voltage > 0 AND f.uc_voltage > 0
    GROUP BY f.ftukey, hour_bucket
)
SELECT 
    d.ftukey AS "设备ID",
    df.devicename AS "设备名称",
    d.hour_bucket AS "时间",
    -- 电流不平衡度计算 (最大偏差/平均值)
    ROUND(100.0 * GREATEST(
        ABS(d.avg_ia - (d.avg_ia + d.avg_ib + d.avg_ic)/3),
        ABS(d.avg_ib - (d.avg_ia + d.avg_ib + d.avg_ic)/3),
        ABS(d.avg_ic - (d.avg_ia + d.avg_ib + d.avg_ic)/3)
    ) / ((d.avg_ia + d.avg_ib + d.avg_ic)/3), 2) AS "电流不平衡度(%)",
    -- 电压不平衡度计算
    ROUND(100.0 * GREATEST(
        ABS(d.avg_ua - (d.avg_ua + d.avg_ub + d.avg_uc)/3),
        ABS(d.avg_ub - (d.avg_ua + d.avg_ub + d.avg_uc)/3),
        ABS(d.avg_uc - (d.avg_ua + d.avg_ub + d.avg_uc)/3)
    ) / ((d.avg_ua + d.avg_ub + d.avg_uc)/3), 2) AS "电压不平衡度(%)"
FROM hourly_data d
JOIN dimftu df ON d.ftukey = df.ftukey
ORDER BY hour_bucket DESC, "电流不平衡度(%)" DESC;

1.3 设备健康评分

-- 设备健康综合评分(过去7天)
WITH parameter_stats AS (
    SELECT 
        f.ftukey,
        -- 三相电流不平衡指标
        AVG(GREATEST(
            ABS(f.ia_current - (f.ia_current + f.ib_current + f.ic_current)/3),
            ABS(f.ib_current - (f.ia_current + f.ib_current + f.ic_current)/3),
            ABS(f.ic_current - (f.ia_current + f.ib_current + f.ic_current)/3)
        ) / NULLIF(((f.ia_current + f.ib_current + f.ic_current)/3), 0)) AS avg_current_imbalance,
        -- 三相电压不平衡指标
        AVG(GREATEST(
            ABS(f.ua_voltage - (f.ua_voltage + f.ub_voltage + f.uc_voltage)/3),
            ABS(f.ub_voltage - (f.ua_voltage + f.ub_voltage + f.uc_voltage)/3),
            ABS(f.uc_voltage - (f.ua_voltage + f.ub_voltage + f.uc_voltage)/3)
        ) / NULLIF(((f.ua_voltage + f.ub_voltage + f.uc_voltage)/3), 0)) AS avg_voltage_imbalance,
        -- 功率因数稳定性
        STDDEV(f.power_cos) AS cos_stability,
        -- 参数超限率计算
        SUM(CASE WHEN f.ua_voltage < 5.79 OR f.ua_voltage > 6.10 THEN 1 ELSE 0 END) +
        SUM(CASE WHEN f.ub_voltage < 5.70 OR f.ub_voltage > 5.94 THEN 1 ELSE 0 END) +
        SUM(CASE WHEN f.uc_voltage < 5.75 OR f.uc_voltage > 5.99 THEN 1 ELSE 0 END) +
        SUM(CASE WHEN f.ia_current < 6.62 OR f.ia_current > 19.23 THEN 1 ELSE 0 END) +
        SUM(CASE WHEN f.ib_current < 5.51 OR f.ib_current > 16.95 THEN 1 ELSE 0 END) +
        SUM(CASE WHEN f.power_cos < 0.68 OR f.power_cos > 1.0 THEN 1 ELSE 0 END) AS total_violations,
        COUNT(*) * 6 AS total_checks -- 6个参数被检查
    FROM factpowerreadings f
    WHERE f.readingtimestamp >= NOW() - INTERVAL '7 days'
    GROUP BY f.ftukey
)
SELECT 
    ps.ftukey AS "设备ID",
    df.devicename AS "设备名称",
    df.feeder AS "馈线",
    df.substation AS "变电站",
    df.powersupplyoffice AS "供电所",
    -- 计算健康分数 (100分满分)
    ROUND(100 - (
        -- 三相不平衡分量(最多扣30分)
        LEAST(30, ROUND(ps.avg_current_imbalance * 100)) - 
        -- 电压不平衡分量(最多扣30分)
        LEAST(30, ROUND(ps.avg_voltage_imbalance * 100)) -
        -- 功率因数不稳定性(最多扣20分)
        LEAST(20, ROUND(ps.cos_stability * 50)) -
        -- 参数超限率(最多扣20分)
        LEAST(20, ROUND(20.0 * ps.total_violations / NULLIF(ps.total_checks, 0)))
    ), 2) AS "健康评分",
    ROUND(100.0 * ps.total_violations / NULLIF(ps.total_checks, 0), 2) AS "参数超限率(%)",
    ROUND(ps.avg_current_imbalance * 100, 2) AS "平均电流不平衡度(%)",
    ROUND(ps.avg_voltage_imbalance * 100, 2) AS "平均电压不平衡度(%)"
FROM parameter_stats ps
JOIN dimftu df ON ps.ftukey = df.ftukey
ORDER BY "健康评分";

2. 故障预警监控

2.1 可能的短路故障预警

-- 短路故障预警检测(电压骤降+电流骤升)
WITH voltage_current_changes AS (
    SELECT 
        f.ftukey,
        f.readingtimestamp,
        f.ua_voltage, f.ub_voltage, f.uc_voltage,
        f.ia_current, f.ib_current, f.ic_current,
        LAG(f.ua_voltage) OVER (PARTITION BY f.ftukey ORDER BY f.readingtimestamp) AS prev_ua,
        LAG(f.ub_voltage) OVER (PARTITION BY f.ftukey ORDER BY f.readingtimestamp) AS prev_ub,
        LAG(f.uc_voltage) OVER (PARTITION BY f.ftukey ORDER BY f.readingtimestamp) AS prev_uc,
        LAG(f.ia_current) OVER (PARTITION BY f.ftukey ORDER BY f.readingtimestamp) AS prev_ia,
        LAG(f.ib_current) OVER (PARTITION BY f.ftukey ORDER BY f.readingtimestamp) AS prev_ib,
        LAG(f.ic_current) OVER (PARTITION BY f.ftukey ORDER BY f.readingtimestamp) AS prev_ic,
        -- 计算变化率
        CASE WHEN LAG(f.ua_voltage) OVER (PARTITION BY f.ftukey ORDER BY f.readingtimestamp) > 0 
             THEN (f.ua_voltage - LAG(f.ua_voltage) OVER (PARTITION BY f.ftukey ORDER BY f.readingtimestamp)) / 
                  LAG(f.ua_voltage) OVER (PARTITION BY f.ftukey ORDER BY f.readingtimestamp)
             ELSE 0 END AS ua_change_ratio,
        CASE WHEN LAG(f.ia_current) OVER (PARTITION BY f.ftukey ORDER BY f.readingtimestamp) > 0 
             THEN (f.ia_current - LAG(f.ia_current) OVER (PARTITION BY f.ftukey ORDER BY f.readingtimestamp)) / 
                  LAG(f.ia_current) OVER (PARTITION BY f.ftukey ORDER BY f.readingtimestamp)
             ELSE 0 END AS ia_change_ratio
    FROM factpowerreadings f
    WHERE f.readingtimestamp >= NOW() - INTERVAL '3 days'
)
SELECT 
    vc.ftukey AS "设备ID",
    df.devicename AS "设备名称",
    df.feeder AS "馈线",
    vc.readingtimestamp AS "时间",
    ROUND(vc.ua_voltage, 2) AS "UA电压",
    ROUND(vc.prev_ua, 2) AS "先前UA电压",
    ROUND(vc.ua_change_ratio * 100, 2) AS "UA变化率(%)",
    ROUND(vc.ub_voltage, 2) AS "UB电压",
    ROUND(vc.uc_voltage, 2) AS "UC电压",
    ROUND(vc.ia_current, 2) AS "IA电流",
    ROUND(vc.prev_ia, 2) AS "先前IA电流",
    ROUND(vc.ia_change_ratio * 100, 2) AS "IA变化率(%)",
    CASE 
        WHEN (vc.ua_voltage/NULLIF(vc.prev_ua,0) < 0.7 AND vc.ub_voltage/NULLIF(vc.prev_ub,0) < 0.7 AND vc.uc_voltage/NULLIF(vc.prev_uc,0) < 0.7) 
          AND (vc.ia_current/NULLIF(vc.prev_ia,0) > 2 OR vc.ib_current/NULLIF(vc.prev_ib,0) > 2 OR vc.ic_current/NULLIF(vc.prev_ic,0) > 2) 
          THEN 'SC01-可能三相短路'
        WHEN ((vc.ua_voltage/NULLIF(vc.prev_ua,0) < 0.7 AND vc.ub_voltage/NULLIF(vc.prev_ub,0) < 0.7) OR 
              (vc.ub_voltage/NULLIF(vc.prev_ub,0) < 0.7 AND vc.uc_voltage/NULLIF(vc.prev_uc,0) < 0.7) OR 
              (vc.ua_voltage/NULLIF(vc.prev_ua,0) < 0.7 AND vc.uc_voltage/NULLIF(vc.prev_uc,0) < 0.7))
          AND (vc.ia_current/NULLIF(vc.prev_ia,0) > 2 OR vc.ib_current/NULLIF(vc.prev_ib,0) > 2 OR vc.ic_current/NULLIF(vc.prev_ic,0) > 2) 
          THEN 'SC02-可能两相短路'
        WHEN (vc.ua_voltage/NULLIF(vc.prev_ua,0) < 0.7 OR vc.ub_voltage/NULLIF(vc.prev_ub,0) < 0.7 OR vc.uc_voltage/NULLIF(vc.prev_uc,0) < 0.7)
          AND (vc.ia_current/NULLIF(vc.prev_ia,0) > 2 OR vc.ib_current/NULLIF(vc.prev_ib,0) > 2 OR vc.ic_current/NULLIF(vc.prev_ic,0) > 2)
          THEN 'SC03-可能相间短路'
        ELSE '正常'
    END AS "故障预警"
FROM voltage_current_changes vc
JOIN dimftu df ON vc.ftukey = df.ftukey
WHERE 
    (vc.ua_voltage/NULLIF(vc.prev_ua,0) < 0.8 OR vc.ub_voltage/NULLIF(vc.prev_ub,0) < 0.8 OR vc.uc_voltage/NULLIF(vc.prev_uc,0) < 0.8)
    OR (vc.ia_current/NULLIF(vc.prev_ia,0) > 1.5 OR vc.ib_current/NULLIF(vc.prev_ib,0) > 1.5 OR vc.ic_current/NULLIF(vc.prev_ic,0) > 1.5)
ORDER BY vc.readingtimestamp DESC;

2.2 接地故障监测

-- 接地故障监测(零序电流异常)
SELECT 
    f.ftukey AS "设备ID",
    df.devicename AS "设备名称",
    df.feeder AS "馈线",
    f.readingtimestamp AS "时间",
    ROUND(f.i0_current, 3) AS "零序电流",
    ROUND(f.ia_current, 2) AS "A相电流",
    ROUND(f.ib_current, 2) AS "B相电流",
    ROUND(f.ic_current, 2) AS "C相电流",
    -- 三相电流矢量和,理论上应接近零序电流
    ROUND(SQRT(POWER(f.ia_current, 2) + POWER(f.ib_current, 2) + POWER(f.ic_current, 2) - 
         f.ia_current*f.ib_current - f.ia_current*f.ic_current - f.ib_current*f.ic_current), 3) AS "三相不平衡分量",
    CASE
        WHEN f.i0_current > 0.5 AND f.i0_current/NULLIF((f.ia_current + f.ib_current + f.ic_current)/3, 0) > 0.2
            THEN 'GF01-可能单相接地'
        WHEN f.i0_current > 0.2 AND f.i0_current/NULLIF((f.ia_current + f.ib_current + f.ic_current)/3, 0) > 0.1
            THEN 'GF03-可能高阻接地'
        ELSE '正常'
    END AS "接地故障预警"
FROM factpowerreadings f
JOIN dimftu df ON f.ftukey = df.ftukey
WHERE 
    f.readingtimestamp >= NOW() - INTERVAL '7 days'
    AND f.i0_current > 0.1  -- 零序电流阈值
ORDER BY f.i0_current DESC
LIMIT 1000;

2.3 过载监测

-- 设备过载监测
WITH load_stats AS (
    SELECT 
        f.ftukey,
        -- 按小时分组计算负载指标
        time_bucket('1 hour', f.readingtimestamp) AS hour_bucket,
        AVG(f.activePower_total) AS avg_active_power,
        MAX(f.activePower_total) AS max_active_power,
        MIN(f.activePower_total) AS min_active_power,
        -- 计算设备额定功率的估计值 (基于历史数据)
        PERCENTILE_DISC(0.75) WITHIN GROUP (ORDER BY f.activePower_total) AS rated_power_est
    FROM factpowerreadings f
    WHERE 
        f.readingtimestamp >= NOW() - INTERVAL '30 days'
        AND f.activePower_total > 0
    GROUP BY f.ftukey, hour_bucket
)
SELECT 
    ls.ftukey AS "设备ID",
    df.devicename AS "设备名称",
    df.feeder AS "馈线", 
    ls.hour_bucket AS "时间",
    ROUND(ls.avg_active_power, 2) AS "平均功率(kW)",
    ROUND(ls.max_active_power, 2) AS "最大功率(kW)",
    ROUND(ls.rated_power_est, 2) AS "参考额定功率(kW)",
    ROUND(ls.max_active_power / NULLIF(ls.rated_power_est, 0) * 100, 2) AS "负载率(%)",
    CASE
        WHEN ls.max_active_power > ls.rated_power_est * 1.3 THEN 'OL01-持续过载'
        WHEN ls.max_active_power > ls.rated_power_est * 1.1 THEN 'OL02-轻度过载'
        ELSE '正常负载'
    END AS "负载状态"
FROM load_stats ls
JOIN dimftu df ON ls.ftukey = df.ftukey
WHERE ls.max_active_power > ls.rated_power_est * 1.05  -- 显示负载超过额定105%的情况
ORDER BY "负载率(%)" DESC;

3. 长期趋势分析

3.1 参数稳定性趋势

-- 关键参数稳定性趋势(月度)
WITH monthly_stats AS (
    SELECT 
        f.ftukey,
        DATE_TRUNC('month', f.readingtimestamp) AS month,
        -- 电压稳定性统计
        AVG(f.ua_voltage) AS avg_ua,
        STDDEV(f.ua_voltage) AS stddev_ua,
        MAX(f.ua_voltage) - MIN(f.ua_voltage) AS range_ua,
        -- 电流稳定性统计
        AVG(f.ia_current) AS avg_ia,
        STDDEV(f.ia_current) AS stddev_ia,
        MAX(f.ia_current) - MIN(f.ia_current) AS range_ia,
        -- 功率因数统计
        AVG(f.power_cos) AS avg_cos,
        STDDEV(f.power_cos) AS stddev_cos
    FROM factpowerreadings f
    WHERE 
        f.readingtimestamp >= NOW() - INTERVAL '12 months'
        AND f.ua_voltage > 0 AND f.ia_current > 0
    GROUP BY f.ftukey, month
)
SELECT 
    ms.ftukey AS "设备ID",
    df.devicename AS "设备名称",
    ms.month AS "月份",
    ROUND(ms.avg_ua, 2) AS "平均A相电压",
    ROUND(ms.stddev_ua, 4) AS "A相电压标准差",
    ROUND(ms.range_ua, 2) AS "A相电压波动范围",
    -- 标准差/平均值 = 变异系数,衡量稳定性
    ROUND(ms.stddev_ua / ms.avg_ua * 100, 2) AS "A相电压变异系数(%)",
    ROUND(ms.avg_ia, 2) AS "平均A相电流",
    ROUND(ms.stddev_ia, 4) AS "A相电流标准差",
    ROUND(ms.stddev_ia / ms.avg_ia * 100, 2) AS "A相电流变异系数(%)",
    ROUND(ms.avg_cos, 3) AS "平均功率因数",
    ROUND(ms.stddev_cos, 4) AS "功率因数标准差"
FROM monthly_stats ms
JOIN dimftu df ON ms.ftukey = df.ftukey
ORDER BY ms.month DESC, "A相电压变异系数(%)" DESC;

3.2 设备负载特性分析

-- 设备负载特性分析(日负载曲线)
WITH daily_load_profile AS (
    SELECT 
        f.ftukey,
        dt.hour AS hour_of_day,
        AVG(f.activePower_total) AS avg_active_power,
        AVG(f.reactivePower_total) AS avg_reactive_power,
        AVG(f.power_cos) AS avg_power_factor,
        STDDEV(f.activePower_total) AS stddev_active_power
    FROM factpowerreadings f
    JOIN dimtime dt ON f.timestampkey = dt.timestampkey
    WHERE 
        f.readingtimestamp >= NOW() - INTERVAL '30 days'
        AND f.activePower_total > 0
    GROUP BY f.ftukey, dt.hour
    ORDER BY f.ftukey, dt.hour
)
SELECT 
    dlp.ftukey AS "设备ID",
    df.devicename AS "设备名称",
    df.feeder AS "馈线",
    dlp.hour_of_day AS "小时",
    ROUND(dlp.avg_active_power, 2) AS "平均有功功率(kW)",
    ROUND(dlp.avg_reactive_power, 2) AS "平均无功功率(kVar)",
    ROUND(dlp.avg_power_factor, 3) AS "平均功率因数",
    ROUND(dlp.stddev_active_power, 2) AS "有功功率标准差",
    ROUND(dlp.stddev_active_power / NULLIF(dlp.avg_active_power, 0) * 100, 2) AS "负载波动率(%)"
FROM daily_load_profile dlp
JOIN dimftu df ON dlp.ftukey = df.ftukey
ORDER BY dlp.ftukey, dlp.hour_of_day;

3.3 设备健康度变化趋势

-- 设备健康度月度变化趋势
WITH monthly_health_indicators AS (
    SELECT 
        f.ftukey,
        DATE_TRUNC('month', f.readingtimestamp) AS month,
        -- 三相不平衡指标
        AVG(GREATEST(
            ABS(f.ia_current - (f.ia_current + f.ib_current + f.ic_current)/3),
            ABS(f.ib_current - (f.ia_current + f.ib_current + f.ic_current)/3),
            ABS(f.ic_current - (f.ia_current + f.ib_current + f.ic_current)/3)
        ) / NULLIF(((f.ia_current + f.ib_current + f.ic_current)/3), 0)) AS current_imbalance,
        
        AVG(GREATEST(
            ABS(f.ua_voltage - (f.ua_voltage + f.ub_voltage + f.uc_voltage)/3),
            ABS(f.ub_voltage - (f.ua_voltage + f.ub_voltage + f.uc_voltage)/3),
            ABS(f.uc_voltage - (f.ua_voltage + f.ub_voltage + f.uc_voltage)/3)
        ) / NULLIF(((f.ua_voltage + f.ub_voltage + f.uc_voltage)/3), 0)) AS voltage_imbalance,
        
        -- 异常率指标
        SUM(CASE WHEN f.ua_voltage < 5.79 OR f.ua_voltage > 6.10 OR
                   f.ub_voltage < 5.70 OR f.ub_voltage > 5.94 OR
                   f.uc_voltage < 5.75 OR f.uc_voltage > 5.99 OR
                   f.power_cos < 0.68 THEN 1 ELSE 0 END) AS total_abnormal,
        COUNT(*) AS total_readings
    FROM factpowerreadings f
    WHERE f.readingtimestamp >= NOW() - INTERVAL '12 months'
    GROUP BY f.ftukey, month
)
SELECT 
    mhi.ftukey AS "设备ID",
    df.devicename AS "设备名称",
    mhi.month AS "月份",
    -- 计算总健康分数 (满分100)
    ROUND(100 - (
        LEAST(30, mhi.current_imbalance * 100) - 
        LEAST(30, mhi.voltage_imbalance * 100) -
        LEAST(40, 40.0 * mhi.total_abnormal / NULLIF(mhi.total_readings, 0))
    ), 2) AS "健康评分",
    ROUND(mhi.current_imbalance * 100, 2) AS "电流不平衡度(%)",
    ROUND(mhi.voltage_imbalance * 100, 2) AS "电压不平衡度(%)",
    ROUND(100.0 * mhi.total_abnormal / NULLIF(mhi.total_readings, 0), 2) AS "参数异常率(%)"
FROM monthly_health_indicators mhi
JOIN dimftu df ON mhi.ftukey = df.ftukey
ORDER BY mhi.ftukey, mhi.month;

4. 区域与设备对比分析

4.1 变电站设备健康对比

-- 变电站下各设备健康状况对比
WITH device_health AS (
    SELECT 
        f.ftukey,
        -- 三相不平衡度
        AVG(ABS(f.ia_current - (f.ia_current + f.ib_current + f.ic_current)/3) / 
            NULLIF(((f.ia_current + f.ib_current + f.ic_current)/3), 0) +
            ABS(f.ib_current - (f.ia_current + f.ib_current + f.ic_current)/3) / 
            NULLIF(((f.ia_current + f.ib_current + f.ic_current)/3), 0) +
            ABS(f.ic_current - (f.ia_current + f.ib_current + f.ic_current)/3) / 
            NULLIF(((f.ia_current + f.ib_current + f.ic_current)/3), 0)) / 3 AS avg_current_imbalance,
        
        -- 电压稳定性
        STDDEV(f.ua_voltage) / NULLIF(AVG(f.ua_voltage), 0) AS ua_instability,
        STDDEV(f.ub_voltage) / NULLIF(AVG(f.ub_voltage), 0) AS ub_instability,
        STDDEV(f.uc_voltage) / NULLIF(AVG(f.uc_voltage), 0) AS uc_instability,
        
        -- 功率因数稳定性
        STDDEV(f.power_cos) AS cos_stability,
        
        -- 参数超限比例
        SUM(CASE WHEN f.ua_voltage < 5.79 OR f.ua_voltage > 6.10 THEN 1 ELSE 0 END) +
        SUM(CASE WHEN f.ub_voltage < 5.70 OR f.ub_voltage > 5.94 THEN 1 ELSE 0 END) +
        SUM(CASE WHEN f.uc_voltage < 5.75 OR f.uc_voltage > 5.99 THEN 1 ELSE 0 END) +
        SUM(CASE WHEN f.ia_current < 6.62 OR f.ia_current > 19.23 THEN 1 ELSE 0 END) +
        SUM(CASE WHEN f.ib_current < 5.51 OR f.ib_current > 16.95 THEN 1 ELSE 0 END) +
        SUM(CASE WHEN f.power_cos < 0.68 OR f.power_cos > 1.0 THEN 1 ELSE 0 END) AS total_violations,
        
        COUNT(*) * 6 AS total_params_checked
    FROM factpowerreadings f
    WHERE f.readingtimestamp >= NOW() - INTERVAL '30 days'
    GROUP BY f.ftukey
)
SELECT 
    df.substation AS "变电站",
    df.feeder AS "馈线",
    df.ftukey AS "设备ID",
    df.devicename AS "设备名称",
    -- 健康评分计算
    ROUND(100 - (
        LEAST(25, dh.avg_current_imbalance * 100) - 
        LEAST(25, (dh.ua_instability + dh.ub_instability + dh.uc_instability) * 100 / 3) -
        LEAST(25, dh.cos_stability * 50) -
        LEAST(25, 25.0 * dh.total_violations / NULLIF(dh.total_params_checked, 0))
    ), 2) AS "健康评分",
    ROUND(dh.avg_current_imbalance * 100, 2) AS "电流不平衡度(%)",
    ROUND((dh.ua_instability + dh.ub_instability + dh.uc_instability) * 100 / 3, 2) AS "电压不稳定度(%)",
    ROUND(100.0 * dh.total_violations / NULLIF(dh.total_params_checked, 0), 2) AS "参数超限率(%)"
FROM device_health dh
JOIN dimftu df ON dh.ftukey = df.ftukey
ORDER BY df.substation, "健康评分";

4.2 馈线健康评级

-- 馈线健康等级评估
WITH feeder_health AS (
    SELECT 
        df.substation,
        df.feeder,
        COUNT(DISTINCT f.ftukey) AS device_count,
        -- 各种健康指标的平均值
        AVG(
            GREATEST(
                ABS(f.ia_current - (f.ia_current + f.ib_current + f.ic_current)/3),
                ABS(f.ib_current - (f.ia_current + f.ib_current + f.ic_current)/3),
                ABS(f.ic_current - (f.ia_current + f.ib_current + f.ic_current)/3)
            ) / NULLIF(((f.ia_current + f.ib_current + f.ic_current)/3), 0)
        ) AS avg_current_imbalance,
        
        AVG(STDDEV(f.ua_voltage) / NULLIF(AVG(f.ua_voltage), 0)) OVER (PARTITION BY df.feeder) AS avg_voltage_instability,
        
        SUM(CASE WHEN f.ua_voltage < 5.79 OR f.ua_voltage > 6.10 OR
                   f.ub_voltage < 5.70 OR f.ub_voltage > 5.94 OR
                   f.uc_voltage < 5.75 OR f.uc_voltage > 5.99 OR
                   f.ia_current < 6.62 OR f.ia_current > 19.23 OR
                   f.ib_current < 5.51 OR f.ib_current > 16.95 OR
                   f.power_cos < 0.68 THEN 1 ELSE 0 END) AS total_violations,
                   
        COUNT(*) * 6 AS total_checks
    FROM factpowerreadings f
    JOIN dimftu df ON f.ftukey = df.ftukey
    WHERE 
        f.readingtimestamp >= NOW() - INTERVAL '30 days'
        AND df.feeder IS NOT NULL
    GROUP BY df.substation, df.feeder
)
SELECT 
    substation AS "变电站",
    feeder AS "馈线",
    device_count AS "设备数量",
    ROUND(100 - (
        LEAST(30, avg_current_imbalance * 100) - 
        LEAST(30, avg_voltage_instability * 100) -
        LEAST(40, 40.0 * total_violations / NULLIF(total_checks, 0))
    ), 2) AS "健康评分",
    CASE
        WHEN 100 - (LEAST(30, avg_current_imbalance * 100) - 
                    LEAST(30, avg_voltage_instability * 100) -
                    LEAST(40, 40.0 * total_violations / NULLIF(total_checks, 0))) >= 90 THEN 'A-优'
        WHEN 100 - (LEAST(30, avg_current_imbalance * 100) - 
                    LEAST(30, avg_voltage_instability * 100) -
                    LEAST(40, 40.0 * total_violations / NULLIF(total_checks, 0))) >= 80 THEN 'B-良'
        WHEN 100 - (LEAST(30, avg_current_imbalance * 100) - 
                    LEAST(30, avg_voltage_instability * 100) -
                    LEAST(40, 40.0 * total_violations / NULLIF(total_checks, 0))) >= 70 THEN 'C-中'
        WHEN 100 - (LEAST(30, avg_current_imbalance * 100) - 
                    LEAST(30, avg_voltage_instability * 100) -
                    LEAST(40, 40.0 * total_violations / NULLIF(total_checks, 0))) >= 60 THEN 'D-差'
        ELSE 'E-劣'
    END AS "健康等级",
    ROUND(avg_current_imbalance * 100, 2) AS "平均电流不平衡度(%)",
    ROUND(avg_voltage_instability * 100, 2) AS "平均电压不稳定度(%)",
    ROUND(100.0 * total_violations / NULLIF(total_checks, 0), 2) AS "参数超限率(%)"
FROM feeder_health
ORDER BY "健康评分" DESC;

4.3 区域故障风险地图数据

-- 区域故障风险评估(基于地理位置)
WITH location_risks AS (
    SELECT 
        df.ftukey,
        df.latitude,
        df.longitude,
        df.city,
        df.county,
        df.powersupplyoffice,
        -- 故障风险指标
        AVG(GREATEST(
            ABS(f.ia_current - (f.ia_current + f.ib_current + f.ic_current)/3),
            ABS(f.ib_current - (f.ia_current + f.ib_current + f.ic_current)/3),
            ABS(f.ic_current - (f.ia_current + f.ib_current + f.ic_current)/3)
        ) / NULLIF(((f.ia_current + f.ib_current + f.ic_current)/3), 0)) * 30 + -- 电流不平衡分量
        
        AVG(GREATEST(
            ABS(f.ua_voltage - (f.ua_voltage + f.ub_voltage + f.uc_voltage)/3),
            ABS(f.ub_voltage - (f.ua_voltage + f.ub_voltage + f.uc_voltage)/3),
            ABS(f.uc_voltage - (f.ua_voltage + f.ub_voltage + f.uc_voltage)/3)
        ) / NULLIF(((f.ua_voltage + f.ub_voltage + f.uc_voltage)/3), 0)) * 20 + -- 电压不平衡分量
        
        (SUM(CASE WHEN f.ua_voltage < 5.79 OR f.ua_voltage > 6.10 OR
                     f.ub_voltage < 5.70 OR f.ub_voltage > 5.94 OR
                     f.uc_voltage < 5.75 OR f.uc_voltage > 5.99 OR
                     f.power_cos < 0.68 THEN 1 ELSE 0 END) * 1.0 / 
         NULLIF(COUNT(*), 0)) * 50 AS risk_score -- 参数超限分量
    FROM factpowerreadings f
    JOIN dimftu df ON f.ftukey = df.ftukey
    WHERE 
        f.readingtimestamp >= NOW() - INTERVAL '30 days'
        AND df.latitude IS NOT NULL AND df.longitude IS NOT NULL
    GROUP BY df.ftukey, df.latitude, df.longitude, df.city, df.county, df.powersupplyoffice
)
SELECT 
    ftukey AS "设备ID",
    latitude AS "纬度",
    longitude AS "经度",
    city AS "城市",
    county AS "区县",
    powersupplyoffice AS "供电所",
    ROUND(risk_score, 2) AS "风险评分",
    CASE
        WHEN risk_score >= 40 THEN '高风险'
        WHEN risk_score >= 20 THEN '中风险'
        ELSE '低风险'
    END AS "风险等级"
FROM location_risks
ORDER BY risk_score DESC;

5. 设备异常预警

5.1 设备异常预警综合评估

-- 设备异常预警(综合多种故障特征)
WITH device_warnings AS (
    SELECT 
        f.ftukey,
        -- 电压异常
        SUM(CASE WHEN (f.ua_voltage < 5.79 OR f.ua_voltage > 6.10) AND
                       (f.ub_voltage < 5.70 OR f.ub_voltage > 5.94) AND
                       (f.uc_voltage < 5.75 OR f.uc_voltage > 5.99)
                  THEN 1 ELSE 0 END) AS three_phase_voltage_abnormal,
                  
        -- 电流异常      
        SUM(CASE WHEN (f.ia_current < 6.62 OR f.ia_current > 19.23) AND
                       (f.ib_current < 5.51 OR f.ib_current > 16.95)
                  THEN 1 ELSE 0 END) AS current_abnormal,
                  
        -- 三相不平衡异常
        SUM(CASE WHEN GREATEST(
                ABS(f.ia_current - (f.ia_current + f.ib_current + f.ic_current)/3),
                ABS(f.ib_current - (f.ia_current + f.ib_current + f.ic_current)/3),
                ABS(f.ic_current - (f.ia_current + f.ib_current + f.ic_current)/3)
            ) / NULLIF(((f.ia_current + f.ib_current + f.ic_current)/3), 0) > 0.2
            THEN 1 ELSE 0 END) AS imbalance_abnormal,
            
        -- 功率因数异常
        SUM(CASE WHEN f.power_cos < 0.68 THEN 1 ELSE 0 END) AS cos_abnormal,
        
        -- 零序电流异常
        SUM(CASE WHEN f.i0_current > 0.2 THEN 1 ELSE 0 END) AS zero_seq_current_abnormal,
        
        -- 总记录数
        COUNT(*) AS total_records,
        
        -- 最近数据时间
        MAX(f.readingtimestamp) AS latest_reading
    FROM factpowerreadings f
    WHERE f.readingtimestamp >= NOW() - INTERVAL '7 days'
    GROUP BY f.ftukey
)
SELECT 
    dw.ftukey AS "设备ID",
    df.devicename AS "设备名称",
    df.feeder AS "馈线",
    dw.latest_reading AS "最新数据时间",
    -- 异常统计
    dw.three_phase_voltage_abnormal AS "三相电压异常次数",
    dw.current_abnormal AS "电流异常次数",
    dw.imbalance_abnormal AS "三相不平衡次数",
    dw.cos_abnormal AS "功率因数异常次数",
    dw.zero_seq_current_abnormal AS "零序电流异常次数",
    -- 异常率计算
    ROUND(100.0 * (dw.three_phase_voltage_abnormal + dw.current_abnormal + 
          dw.imbalance_abnormal + dw.cos_abnormal + dw.zero_seq_current_abnormal) / 
          (dw.total_records * 5), 2) AS "异常率(%)",
    -- 预警级别
    CASE
        WHEN 100.0 * (dw.three_phase_voltage_abnormal + dw.current_abnormal + 
             dw.imbalance_abnormal + dw.cos_abnormal + dw.zero_seq_current_abnormal) / 
             (dw.total_records * 5) >= 20 THEN '严重预警'
        WHEN 100.0 * (dw.three_phase_voltage_abnormal + dw.current_abnormal + 
             dw.imbalance_abnormal + dw.cos_abnormal + dw.zero_seq_current_abnormal) / 
             (dw.total_records * 5) >= 10 THEN '中度预警'
        WHEN 100.0 * (dw.three_phase_voltage_abnormal + dw.current_abnormal + 
             dw.imbalance_abnormal + dw.cos_abnormal + dw.zero_seq_current_abnormal) / 
             (dw.total_records * 5) >= 5 THEN '轻度预警'
        ELSE '正常'
    END AS "预警级别",
    -- 可能故障类型
    CASE
        WHEN dw.three_phase_voltage_abnormal > 0 AND dw.current_abnormal > 0 AND dw.imbalance_abnormal > 0
            THEN '可能短路故障(SC)'
        WHEN dw.zero_seq_current_abnormal > 0 AND dw.three_phase_voltage_abnormal > 0
            THEN '可能接地故障(GF)'
        WHEN dw.three_phase_voltage_abnormal > 0 AND dw.imbalance_abnormal = 0
            THEN '可能失压故障(VL)'
        WHEN dw.current_abnormal > 0 AND dw.cos_abnormal > 0
            THEN '可能过载故障(OL)'
        WHEN dw.imbalance_abnormal > 0
            THEN '可能三相不平衡(AC02/AV02)'
        ELSE '无明确故障类型'
    END AS "可能故障类型"
FROM device_warnings dw
JOIN dimftu df ON dw.ftukey = df.ftukey
WHERE dw.three_phase_voltage_abnormal > 0 
   OR dw.current_abnormal > 0 
   OR dw.imbalance_abnormal > 0 
   OR dw.cos_abnormal > 0 
   OR dw.zero_seq_current_abnormal > 0
ORDER BY "异常率(%)" DESC;

这些SQL查询可以直接添加到Metabase中,为您提供设备健康状况的全面监控。您可以根据需要调整阈值参数和时间范围。对于长期监控,建议创建以下仪表板:

  1. 设备健康概览:包含健康评分、参数异常统计
  2. 故障预警监控:短路、接地、过载等故障预警
  3. 长期趋势分析:设备参数稳定性、负载特性和健康度变化
  4. 区域分析:变电站、馈线健康状况对比

这些查询采用TimescaleDB的时间分析功能和阈值报告中的参数范围,能够有效识别潜在故障并提供长期监控支持。