223 lines
7.6 KiB
SQL
223 lines
7.6 KiB
SQL
-- 根据现有ss_sensor_data_schema.sql创建示例数据
|
||
-- 为学生用户生成传感器数据以供演示
|
||
|
||
-- 首先确保表结构存在
|
||
-- 如果还没有运行过ss_sensor_data_schema.sql,请先运行
|
||
|
||
-- 生成示例数据
|
||
DO $$
|
||
DECLARE
|
||
demo_user_id UUID;
|
||
demo_device_id UUID;
|
||
measurement_id UUID;
|
||
current_time TIMESTAMPTZ;
|
||
i INTEGER;
|
||
BEGIN
|
||
-- 查找第一个学生用户ID
|
||
SELECT id INTO demo_user_id
|
||
FROM public.ak_users
|
||
WHERE role = 'student'
|
||
LIMIT 1;
|
||
|
||
-- 创建或查找一个示例设备
|
||
SELECT id INTO demo_device_id
|
||
FROM public.ak_devices
|
||
LIMIT 1;
|
||
|
||
-- 如果没有设备,创建一个示例设备
|
||
IF demo_device_id IS NULL THEN
|
||
INSERT INTO public.ak_devices (id, name, type, model, created_at)
|
||
VALUES (
|
||
uuid_generate_v4(),
|
||
'健康监测设备',
|
||
'health_monitor',
|
||
'HealthTracker Pro',
|
||
NOW()
|
||
)
|
||
RETURNING id INTO demo_device_id;
|
||
|
||
RAISE NOTICE '创建了示例设备: %', demo_device_id;
|
||
END IF;
|
||
|
||
-- 如果找到学生用户,插入示例数据
|
||
IF demo_user_id IS NOT NULL AND demo_device_id IS NOT NULL THEN
|
||
current_time := NOW();
|
||
|
||
-- 生成最近7天的体温数据(每4小时一条)
|
||
FOR i IN 0..41 LOOP
|
||
-- 插入到主表
|
||
INSERT INTO public.ss_sensor_measurements (
|
||
id, device_id, user_id, measurement_type, measured_at, unit, raw_data
|
||
) VALUES (
|
||
uuid_generate_v4(),
|
||
demo_device_id,
|
||
demo_user_id,
|
||
'temp',
|
||
current_time - (interval '4 hours' * i),
|
||
'°C',
|
||
jsonb_build_object('temperature_c', 36.0 + (random() * 1.5))
|
||
)
|
||
RETURNING id INTO measurement_id;
|
||
|
||
-- 插入到专项表
|
||
INSERT INTO public.ss_temperature (measurement_id, temperature_c)
|
||
SELECT measurement_id, (raw_data->>'temperature_c')::FLOAT
|
||
FROM public.ss_sensor_measurements
|
||
WHERE id = measurement_id;
|
||
END LOOP;
|
||
|
||
-- 生成最近7天的心率数据(每2小时一条)
|
||
FOR i IN 0..83 LOOP
|
||
-- 插入到主表
|
||
INSERT INTO public.ss_sensor_measurements (
|
||
id, device_id, user_id, measurement_type, measured_at, unit, raw_data
|
||
) VALUES (
|
||
uuid_generate_v4(),
|
||
demo_device_id,
|
||
demo_user_id,
|
||
'heart_rate',
|
||
current_time - (interval '2 hours' * i),
|
||
'bpm',
|
||
jsonb_build_object('heart_rate_bpm', 60 + (random() * 40)::INT)
|
||
)
|
||
RETURNING id INTO measurement_id;
|
||
|
||
-- 插入到专项表
|
||
INSERT INTO public.ss_heart_rate (measurement_id, heart_rate_bpm)
|
||
SELECT measurement_id, (raw_data->>'heart_rate_bpm')::INT
|
||
FROM public.ss_sensor_measurements
|
||
WHERE id = measurement_id;
|
||
END LOOP;
|
||
|
||
-- 生成最近7天的血氧数据(每6小时一条)
|
||
FOR i IN 0..27 LOOP
|
||
-- 插入到主表
|
||
INSERT INTO public.ss_sensor_measurements (
|
||
id, device_id, user_id, measurement_type, measured_at, unit, raw_data
|
||
) VALUES (
|
||
uuid_generate_v4(),
|
||
demo_device_id,
|
||
demo_user_id,
|
||
'spo2',
|
||
current_time - (interval '6 hours' * i),
|
||
'%',
|
||
jsonb_build_object('spo2_percent', 95 + (random() * 5)::INT)
|
||
)
|
||
RETURNING id INTO measurement_id;
|
||
|
||
-- 插入到专项表
|
||
INSERT INTO public.ss_spo2 (measurement_id, spo2_percent)
|
||
SELECT measurement_id, (raw_data->>'spo2_percent')::INT
|
||
FROM public.ss_sensor_measurements
|
||
WHERE id = measurement_id;
|
||
END LOOP;
|
||
|
||
-- 生成最近7天的步数数据(每天一条)
|
||
FOR i IN 0..6 LOOP
|
||
-- 插入到主表
|
||
INSERT INTO public.ss_sensor_measurements (
|
||
id, device_id, user_id, measurement_type, measured_at, unit, raw_data
|
||
) VALUES (
|
||
uuid_generate_v4(),
|
||
demo_device_id,
|
||
demo_user_id,
|
||
'steps',
|
||
current_time - (interval '1 day' * i),
|
||
'count',
|
||
jsonb_build_object('step_count', 5000 + (random() * 10000)::BIGINT)
|
||
)
|
||
RETURNING id INTO measurement_id;
|
||
|
||
-- 插入到专项表
|
||
INSERT INTO public.ss_steps (measurement_id, step_count)
|
||
SELECT measurement_id, (raw_data->>'step_count')::BIGINT
|
||
FROM public.ss_sensor_measurements
|
||
WHERE id = measurement_id;
|
||
END LOOP;
|
||
|
||
RAISE NOTICE '成功为用户 % 生成传感器数据', demo_user_id;
|
||
RAISE NOTICE '使用设备ID: %', demo_device_id;
|
||
RAISE NOTICE '生成数据: 体温42条, 心率84条, 血氧28条, 步数7条';
|
||
ELSE
|
||
RAISE NOTICE '未找到学生用户或设备,跳过示例数据生成';
|
||
RAISE NOTICE '学生用户ID: %, 设备ID: %', demo_user_id, demo_device_id;
|
||
END IF;
|
||
END $$;
|
||
|
||
-- 创建一个用于获取最新传感器数据的视图
|
||
CREATE OR REPLACE VIEW public.v_latest_student_health AS
|
||
WITH latest_temp AS (
|
||
SELECT DISTINCT ON (sm.user_id)
|
||
sm.user_id,
|
||
st.temperature_c,
|
||
sm.measured_at as temp_time
|
||
FROM public.ss_sensor_measurements sm
|
||
JOIN public.ss_temperature st ON st.measurement_id = sm.id
|
||
WHERE sm.measurement_type = 'temp'
|
||
ORDER BY sm.user_id, sm.measured_at DESC
|
||
),
|
||
latest_heart AS (
|
||
SELECT DISTINCT ON (sm.user_id)
|
||
sm.user_id,
|
||
sh.heart_rate_bpm,
|
||
sm.measured_at as heart_time
|
||
FROM public.ss_sensor_measurements sm
|
||
JOIN public.ss_heart_rate sh ON sh.measurement_id = sm.id
|
||
WHERE sm.measurement_type = 'heart_rate'
|
||
ORDER BY sm.user_id, sm.measured_at DESC
|
||
),
|
||
latest_spo2 AS (
|
||
SELECT DISTINCT ON (sm.user_id)
|
||
sm.user_id,
|
||
ss.spo2_percent,
|
||
sm.measured_at as spo2_time
|
||
FROM public.ss_sensor_measurements sm
|
||
JOIN public.ss_spo2 ss ON ss.measurement_id = sm.id
|
||
WHERE sm.measurement_type = 'spo2'
|
||
ORDER BY sm.user_id, sm.measured_at DESC
|
||
),
|
||
latest_steps AS (
|
||
SELECT DISTINCT ON (sm.user_id)
|
||
sm.user_id,
|
||
sst.step_count,
|
||
sm.measured_at as steps_time
|
||
FROM public.ss_sensor_measurements sm
|
||
JOIN public.ss_steps sst ON sst.measurement_id = sm.id
|
||
WHERE sm.measurement_type = 'steps'
|
||
ORDER BY sm.user_id, sm.measured_at DESC
|
||
)
|
||
SELECT
|
||
u.id as user_id,
|
||
u.name,
|
||
u.student_id,
|
||
u.avatar,
|
||
lt.temperature_c,
|
||
lt.temp_time,
|
||
lh.heart_rate_bpm,
|
||
lh.heart_time,
|
||
ls.spo2_percent,
|
||
ls.spo2_time,
|
||
lst.step_count,
|
||
lst.steps_time
|
||
FROM public.ak_users u
|
||
LEFT JOIN latest_temp lt ON lt.user_id = u.id
|
||
LEFT JOIN latest_heart lh ON lh.user_id = u.id
|
||
LEFT JOIN latest_spo2 ls ON ls.user_id = u.id
|
||
LEFT JOIN latest_steps lst ON lst.user_id = u.id
|
||
WHERE u.role = 'student';
|
||
|
||
-- 授予权限
|
||
GRANT SELECT ON public.v_latest_student_health TO authenticated;
|
||
|
||
COMMENT ON VIEW public.v_latest_student_health IS '获取所有学生的最新健康数据,包括体温、心率、血氧、步数';
|
||
|
||
-- 显示统计信息
|
||
SELECT
|
||
measurement_type,
|
||
COUNT(*) as record_count,
|
||
MIN(measured_at) as earliest_record,
|
||
MAX(measured_at) as latest_record
|
||
FROM public.ss_sensor_measurements
|
||
GROUP BY measurement_type
|
||
ORDER BY measurement_type;
|