QDAirPortBackend0122/sql/validate_traffic_light_data.sql
2026-01-22 13:19:47 +08:00

154 lines
4.6 KiB
SQL

-- 红绿灯系统数据验证脚本
-- 用于验证数据完整性和约束
-- 1. 验证路口数据
SELECT 'Intersection Validation' as validation_type;
-- 检查路口数据完整性
SELECT
COUNT(*) as total_intersections,
COUNT(CASE WHEN is_active = true THEN 1 END) as active_intersections,
COUNT(CASE WHEN latitude IS NULL OR longitude IS NULL THEN 1 END) as missing_coordinates
FROM intersections;
-- 检查坐标范围是否合理
SELECT
intersection_id,
intersection_name,
latitude,
longitude,
CASE
WHEN latitude < -90 OR latitude > 90 THEN 'Invalid latitude'
WHEN longitude < -180 OR longitude > 180 THEN 'Invalid longitude'
ELSE 'Valid coordinates'
END as coordinate_status
FROM intersections
WHERE latitude < -90 OR latitude > 90 OR longitude < -180 OR longitude > 180;
-- 2. 验证红绿灯设备数据
SELECT 'Traffic Light Device Validation' as validation_type;
-- 检查设备数据完整性
SELECT
COUNT(*) as total_devices,
COUNT(CASE WHEN is_active = true THEN 1 END) as active_devices,
COUNT(CASE WHEN is_online = true THEN 1 END) as online_devices,
COUNT(CASE WHEN intersection_id IS NULL THEN 1 END) as orphaned_devices
FROM traffic_lights;
-- 检查设备与路口的关联关系
SELECT
tl.device_id,
tl.device_name,
tl.intersection_id,
CASE
WHEN i.intersection_id IS NULL THEN 'Orphaned device - intersection not found'
WHEN i.is_active = false THEN 'Device linked to inactive intersection'
ELSE 'Valid association'
END as association_status
FROM traffic_lights tl
LEFT JOIN intersections i ON tl.intersection_id = i.intersection_id
WHERE i.intersection_id IS NULL OR i.is_active = false;
-- 3. 验证外键约束
SELECT 'Foreign Key Validation' as validation_type;
-- 检查是否有违反外键约束的数据
SELECT
tl.device_id,
tl.intersection_id,
'Missing intersection reference' as issue
FROM traffic_lights tl
WHERE NOT EXISTS (
SELECT 1 FROM intersections i
WHERE i.intersection_id = tl.intersection_id
);
-- 4. 统计信息
SELECT 'Statistics' as validation_type;
-- 按区域统计路口数量
SELECT
area_code,
COUNT(*) as intersection_count,
COUNT(CASE WHEN is_active = true THEN 1 END) as active_count
FROM intersections
GROUP BY area_code
ORDER BY area_code;
-- 按路口统计设备数量
SELECT
i.intersection_id,
i.intersection_name,
COUNT(tl.device_id) as device_count,
COUNT(CASE WHEN tl.is_active = true THEN 1 END) as active_device_count,
COUNT(CASE WHEN tl.is_online = true THEN 1 END) as online_device_count
FROM intersections i
LEFT JOIN traffic_lights tl ON i.intersection_id = tl.intersection_id
GROUP BY i.intersection_id, i.intersection_name
ORDER BY i.intersection_id;
-- 按制造商统计设备数量
SELECT
manufacturer,
COUNT(*) as device_count,
COUNT(CASE WHEN is_active = true THEN 1 END) as active_count,
COUNT(CASE WHEN is_online = true THEN 1 END) as online_count
FROM traffic_lights
WHERE manufacturer IS NOT NULL
GROUP BY manufacturer
ORDER BY device_count DESC;
-- 5. 数据质量检查
SELECT 'Data Quality Check' as validation_type;
-- 检查重复的路口编号
SELECT
intersection_id,
COUNT(*) as duplicate_count
FROM intersections
GROUP BY intersection_id
HAVING COUNT(*) > 1;
-- 检查重复的设备编号
SELECT
device_id,
COUNT(*) as duplicate_count
FROM traffic_lights
GROUP BY device_id
HAVING COUNT(*) > 1;
-- 检查空值或无效数据
SELECT
'intersections' as table_name,
COUNT(CASE WHEN intersection_id IS NULL OR intersection_id = '' THEN 1 END) as null_ids,
COUNT(CASE WHEN intersection_name IS NULL OR intersection_name = '' THEN 1 END) as null_names,
COUNT(CASE WHEN latitude IS NULL THEN 1 END) as null_latitudes,
COUNT(CASE WHEN longitude IS NULL THEN 1 END) as null_longitudes
FROM intersections
UNION ALL
SELECT
'traffic_lights' as table_name,
COUNT(CASE WHEN device_id IS NULL OR device_id = '' THEN 1 END) as null_ids,
COUNT(CASE WHEN device_name IS NULL OR device_name = '' THEN 1 END) as null_names,
COUNT(CASE WHEN intersection_id IS NULL OR intersection_id = '' THEN 1 END) as null_intersection_ids,
0 as null_longitudes
FROM traffic_lights;
-- 6. 索引使用情况检查
SELECT 'Index Usage Check' as validation_type;
-- 检查索引是否存在
SELECT
schemaname,
tablename,
indexname,
indexdef
FROM pg_indexes
WHERE tablename IN ('intersections', 'traffic_lights')
ORDER BY tablename, indexname;
-- 完成验证
SELECT 'Validation Complete' as status, NOW() as completion_time;