Cuándo usar

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.


Plantilla (genérica)

Objetivo: seleccionar, agrupar y contar por claves dentro de un JSON almacenado en una columna.

Parámetros a reemplazar

-- (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


Ejemplo (referencial)

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');


Buenas prácticas de performance (opcional pero recomendado)

1) Columnas calculadas persistidas + índice