I have some performance issues when querying in SQL server. I need to GROUP BY foreign key (academic_unit_id), but I also need to select a column that is dependant on the FK (academic_unit_name). In SQL Server I can't just select academic_unit_name in the same query, it must be aggregated or in the GROUP BY. I think the options I have are:
- SELECT academic_unit_id (foreign key) and academic_unit_unit_name (dependant on FK), and then group by both
SELECT
ria.COD_DOCENTE_SCD,
ria.COD_CURSO_SECCION_SCD,
ria.COD_ITEM_SCD,
ria.COD_GRUPO_PREGUNTA_SCD,
alumno.IDN_UNIDAD_ACADEM_SCD, -- id
alumno.NOM_UNIDAD_ACADEM_SCD, -- name
ROUND(COUNT(case when opcion.punto = 1 then 1 end), 2) as amount_yes,
ROUND(COUNT(case when opcion.punto = 0 then 1 end), 2) as amount_no
FROM BANNER_ENCUESTA.R_RESP_ITEM_ALUMNO_CSP_SCD AS ria INNER JOIN
BANNER_ENCUESTA.TIPO_OPCION_SCD AS opcion ON ria.COD_TIPO_OPCION_SCD = opcion.COD_TIPO_OPCION_SCD INNER JOIN
BANNER_ENCUESTA.ALUMNO_SCD AS alumno ON ria.COD_ALUMNO_SCD = alumno.COD_ALUMNO_SCD
GROUP BY
ria.COD_DOCENTE_SCD,
ria.COD_CURSO_SECCION_SCD,
ria.COD_ITEM_SCD,
ria.COD_GRUPO_PREGUNTA_SCD,
alumno.IDN_UNIDAD_ACADEM_SCD, -- group by FK
alumno.NOM_UNIDAD_ACADEM_SCD -- group by name
- GROUP BY PK and aggregate the academic_unit_name. I can aggregate using max, since all names are equals for a given id.
SELECT
ria.COD_DOCENTE_SCD,
ria.COD_CURSO_SECCION_SCD,
ria.COD_ITEM_SCD,
ria.COD_GRUPO_PREGUNTA_SCD,
alumno.IDN_UNIDAD_ACADEM_SCD, -- id
MAX(alumno.NOM_UNIDAD_ACADEM_SCD), -- aggregate name
ROUND(COUNT(case when opcion.punto = 1 then 1 end), 2) as amount_yes,
ROUND(COUNT(case when opcion.punto = 0 then 1 end), 2) as amount_no
FROM BANNER_ENCUESTA.R_RESP_ITEM_ALUMNO_CSP_SCD AS ria INNER JOIN
BANNER_ENCUESTA.TIPO_OPCION_SCD AS opcion ON ria.COD_TIPO_OPCION_SCD = opcion.COD_TIPO_OPCION_SCD INNER JOIN
BANNER_ENCUESTA.ALUMNO_SCD AS alumno ON ria.COD_ALUMNO_SCD = alumno.COD_ALUMNO_SCD
GROUP BY
ria.COD_DOCENTE_SCD,
ria.COD_CURSO_SECCION_SCD,
ria.COD_ITEM_SCD,
ria.COD_GRUPO_PREGUNTA_SCD,
alumno.IDN_UNIDAD_ACADEM_SCD --Group by FK
- SELECT only academic_unit_id and then JOIN with AcademicUnit again to obtain the name.
with banner_questions as (
SELECT
ria.COD_DOCENTE_SCD,
ria.COD_CURSO_SECCION_SCD,
ria.COD_ITEM_SCD,
ria.COD_GRUPO_PREGUNTA_SCD,
alumno.IDN_UNIDAD_ACADEM_SCD -- id,
ROUND(COUNT(case when opcion.punto = 1 then 1 end), 2) as amount_yes,
ROUND(COUNT(case when opcion.punto = 0 then 1 end), 2) as amount_no
FROM BANNER_ENCUESTA.R_RESP_ITEM_ALUMNO_CSP_SCD AS ria INNER JOIN
BANNER_ENCUESTA.TIPO_OPCION_SCD AS opcion ON ria.COD_TIPO_OPCION_SCD = opcion.COD_TIPO_OPCION_SCD INNER JOIN
BANNER_ENCUESTA.ALUMNO_SCD AS alumno ON ria.COD_ALUMNO_SCD = alumno.COD_ALUMNO_SCD
GROUP BY
ria.COD_DOCENTE_SCD,
ria.COD_CURSO_SECCION_SCD,
ria.COD_ITEM_SCD,
ria.COD_GRUPO_PREGUNTA_SCD,
alumno.IDN_UNIDAD_ACADEM_SCD) -- group by FK
SELECT
banner_questions.*,
student_ua.name -- Join with name
from NORMALIZADO_PRELIMINAR.AcademicUnit as student_ua INNER JOIN
banner_questions on student_ua.id = banner_questions.IDN_UNIDAD_ACADEM_SCD
In terms of performance, I'd like to know if one of these alternatives is better and under what assummptions. Also, I'd like to know if there are better choices to get the same result.