Cuando tenés una tabla con una columna NVARCHAR que guarda un JSON y necesitás extraer campos (valores escalares) y agrupar/contar por esos campos.
Objetivo: seleccionar, agrupar y contar por claves dentro de un JSON almacenado en una columna.
Parámetros a reemplazar
YourTable → nombre de tu tablaYourJsonColumn → columna que contiene el JSON (NVARCHAR)key1, key2, key3 → rutas JSON a extraer (claves top-level o anidadas)extra_col → cualquier otra columna “normal” por la que quieras agruparyour_filters → filtros de negocio-- (Opcional) Validar que la fila tenga JSON bien formado
-- WHERE ISJSON(YourJsonColumn) = 1
SELECT
t.extra_col, -- opcional
JSON_VALUE(t.[YourJsonColumn], '$.key1') AS key1,
JSON_VALUE(t.[YourJsonColumn], '$.key2') AS key2,
JSON_VALUE(t.[YourJsonColumn], '$.key3') AS key3,
COUNT(*) AS Total,
SUM(CASE WHEN <condicion_pendiente> THEN 1 ELSE 0 END) AS Pendiente, -- opcional
SUM(CASE WHEN <condicion_respondido> THEN 1 ELSE 0 END) AS Respondido -- opcional
FROM YourTable AS t
WHERE
/* your_filters */
/* AND ISJSON(t.[YourJsonColumn]) = 1 */ -- útil si hay datos “sucios”
GROUP BY
t.extra_col, -- opcional
JSON_VALUE(t.[YourJsonColumn], '$.key1'),
JSON_VALUE(t.[YourJsonColumn], '$.key2'),
JSON_VALUE(t.[YourJsonColumn], '$.key3')
ORDER BY
t.extra_col, -- opcional
JSON_VALUE(t.[YourJsonColumn], '$.key1'),
JSON_VALUE(t.[YourJsonColumn], '$.key2'),
JSON_VALUE(t.[YourJsonColumn], '$.key3');
Notas
- Usá
$.keypara claves top-level y rutas tipo$.obj.anidado.keypara anidadas.JSON_VALUEdevuelve NVARCHAR(4000); ideal para valores escalares.- Para objetos/arrays completos, usar
JSON_QUERY.- Para “desarmar” arrays y hacer JOINs, usar
OPENJSON.
Tabla polls con columna Data (JSON). Agrupar por Carrera, CodMateria, Materia, Docente:
SELECT
p.reminderid,
JSON_VALUE(p.[Data], '$.Carrera') AS Carrera,
JSON_VALUE(p.[Data], '$.CodMateria') AS CodMateria,
JSON_VALUE(p.[Data], '$.Materia') AS Materia,
JSON_VALUE(p.[Data], '$.Docente') AS Docente,
COUNT(*) AS Total,
SUM(CASE WHEN EndStamp IS NULL THEN 1 ELSE 0 END) AS Pendiente,
SUM(CASE WHEN EndStamp IS NULL THEN 0 ELSE 1 END) AS Respondido
FROM polls AS p
WHERE
idPollType = 5326
AND reminderid IN (461,462,463)
GROUP BY
p.reminderid,
JSON_VALUE(p.[Data], '$.Carrera'),
JSON_VALUE(p.[Data], '$.CodMateria'),
JSON_VALUE(p.[Data], '$.Materia'),
JSON_VALUE(p.[Data], '$.Docente')
ORDER BY
p.reminderid,
JSON_VALUE(p.[Data], '$.Carrera'),
JSON_VALUE(p.[Data], '$.CodMateria'),
JSON_VALUE(p.[Data], '$.Materia'),
JSON_VALUE(p.[Data], '$.Docente');