fix(rpc): filtrar elementos individuales en carrera_congelada [BUG-001]
Mover el filtro 'Ninguna de las anteriores' del WHERE sobre a.value
al WHERE del subquery expandido, donde opt es ya un elemento individual
resultado de jsonb_array_elements_text. El operador #>> '{}' aplicado
sobre un array jsonb no filtraba elementos sino la representación textual
del array completo.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
-- BUG-001 — Fix filtro "Ninguna de las anteriores" en rpc_me_carrera_congelada
|
||||
--
|
||||
-- PROBLEMA: la migración anterior (20260626000001) dejó en el subquery interno:
|
||||
-- AND a.value #>> '{}' != 'Ninguna de las anteriores'
|
||||
-- El operador `#>> '{}'` aplicado sobre un ARRAY jsonb no extrae elementos;
|
||||
-- convierte todo el array a su representación textual (ej. '["opcion","Ninguna..."]'),
|
||||
-- por lo que la comparación nunca descarta el elemento deseado.
|
||||
--
|
||||
-- SOLUCIÓN: mover el filtro al WHERE del subquery expandido, donde `opt` ya existe
|
||||
-- como elemento individual resultado de jsonb_array_elements_text.
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.rpc_me_carrera_congelada(
|
||||
p_survey_id uuid,
|
||||
p_filters jsonb DEFAULT '{}'::jsonb
|
||||
)
|
||||
RETURNS jsonb
|
||||
LANGUAGE plpgsql STABLE SECURITY DEFINER
|
||||
SET search_path = public
|
||||
AS $$
|
||||
DECLARE
|
||||
v_f record;
|
||||
v_n bigint;
|
||||
v_cong bigint;
|
||||
v_rows jsonb;
|
||||
BEGIN
|
||||
SELECT * INTO v_f FROM public._dash_parse_filters(p_filters);
|
||||
|
||||
SELECT
|
||||
count(*),
|
||||
count(*) FILTER (
|
||||
WHERE CASE WHEN jsonb_typeof(a.value) = 'array'
|
||||
THEN jsonb_array_length(a.value - 'Ninguna de las anteriores') > 0
|
||||
ELSE false
|
||||
END
|
||||
)
|
||||
INTO v_n, v_cong
|
||||
FROM public._dash_responses(p_survey_id, v_f.f_depto, v_f.f_genero, v_f.f_etario, v_f.f_modalidad) dr
|
||||
JOIN public.answers a ON a.response_id = dr.response_id
|
||||
JOIN public.questions q ON q.id = a.question_id AND q.code = '7.5'
|
||||
WHERE public._dash_es_cuidador(dr.response_id);
|
||||
|
||||
IF v_n < 5 THEN
|
||||
RETURN jsonb_build_object('status','suppressed','min_n',5,'n',v_n);
|
||||
END IF;
|
||||
|
||||
SELECT jsonb_agg(row ORDER BY cnt DESC) INTO v_rows FROM (
|
||||
SELECT jsonb_build_object('opcion', opt, 'n', cnt, 'pct', ROUND(cnt::numeric / v_n * 100, 1)) AS row,
|
||||
cnt
|
||||
FROM (
|
||||
SELECT opt, count(DISTINCT response_id) AS cnt
|
||||
FROM (
|
||||
SELECT jsonb_array_elements_text(a.value) AS opt,
|
||||
dr.response_id
|
||||
FROM public._dash_responses(p_survey_id, v_f.f_depto, v_f.f_genero, v_f.f_etario, v_f.f_modalidad) dr
|
||||
JOIN public.answers a ON a.response_id = dr.response_id
|
||||
JOIN public.questions q ON q.id = a.question_id AND q.code = '7.5'
|
||||
WHERE public._dash_es_cuidador(dr.response_id)
|
||||
AND jsonb_typeof(a.value) = 'array'
|
||||
) expanded
|
||||
WHERE opt != 'Ninguna de las anteriores'
|
||||
GROUP BY opt
|
||||
) sub
|
||||
WHERE cnt >= 5
|
||||
) t;
|
||||
|
||||
RETURN jsonb_build_object(
|
||||
'status', 'ok',
|
||||
'n', v_n,
|
||||
'pct_carrera_congelada', ROUND(v_cong::numeric / v_n * 100, 1),
|
||||
'top_opciones', COALESCE(v_rows, '[]'::jsonb)
|
||||
);
|
||||
END;
|
||||
$$;
|
||||
Reference in New Issue
Block a user