Principales respuestas
Ayuda para consulta de sql join

Pregunta
-
Buenas tardes grupo, pido su ayuda en una consulta de sql, tengo dos tablas una de materias y otra de calificaciones que son las siguientes:
declare @Materias table (id_materia int,Materia char(100),semestre int)
declare @calificacion table(id_calificacion int,matricula char(10),id_materia int,cal float)insert into @Materias(id_materia,Materia,semestre) values(1,'Matematicas I',1)
insert into @Materias(id_materia,Materia,semestre) values(2,'Qumica I',1)
insert into @Materias(id_materia,Materia,semestre) values(3,'Fisica I',1)
insert into @Materias(id_materia,Materia,semestre) values(4,'Algoritmos I',1)
insert into @Materias(id_materia,Materia,semestre) values(5,'Matematicas II',2)
insert into @Materias(id_materia,Materia,semestre) values(6,'Qumica II',2)
insert into @Materias(id_materia,Materia,semestre) values(7,'Fisica II',2)
insert into @Materias(id_materia,Materia,semestre) values(8,'Algoritmos II',2)insert into @calificacion(id_calificacion,matricula,id_materia,cal)values(1,'101010',1,7.5)
insert into @calificacion(id_calificacion,matricula,id_materia,cal)values(2,'101010',2,8)
insert into @calificacion(id_calificacion,matricula,id_materia,cal)values(3,'101010',3,9)
insert into @calificacion(id_calificacion,matricula,id_materia,cal)values(4,'101010',4,5)y quiero que mi consulta aparezca de la siguiente forma:
Materia cal semestre
Matemáticas I 7.5 1
Química I 8 1
Física I 9 1
Algoritmos I 5 1
Matemáticas II
Química II
Física II
Algoritmos IISegún yo, mi consulta es así
select a.Materia,b.cal,a.semestre
from @Materias a left join @calificacion b on a.id_materia=b.id_materia
where b.matricula='101010'Pero solamente me salen las materias que están en la tabla calificaciones
Materia cal semestre
Matemáticas I 7.5 1
Química I 8 1
Física I 9 1
Algoritmos I 5 1y quiero que salgan todas materias de la tabla Materias, Me pueden ayudar diciéndome en que estoy mal, por favor.
Respuestas
-
Deleted
- Marcado como respuesta Yōichi Hiruma jueves, 21 de junio de 2018 14:31
-
Hola
select b.Materia, isnull(cast(a.cal as varchar(5)),'') as cal, case when a.cal is null then '' else cast(b.semestre as varchar(1)) end as semestre from @Materias b left join @calificacion a on b.id_materia = a.id_materia or a.id_materia is null where a.matricula='101010' or a.matricula is null
Para obtenerlos todos, si filtras por a.matricula, tambien tienes que añadirle donde no tenga.
Un saludo
- Marcado como respuesta Yōichi Hiruma jueves, 21 de junio de 2018 14:30
-
El problema lo tienes en el filtro que haces en la clausula WHERE, como indica Augusto1982.
Repasemos lo que estas haciendo en base a lo que deseas para que des cuentas donde esta el problema.
Si deseas seleccionar todas las materias, independientemente de que se tenga una calificacion o no entonces necesitamos un OUTER JOIN tal como lo has hecho. Esto significa que por cada materia se mostrara la calificacion que macha en el lado derecho o en su vez se mostrara la marca NULL. Si tu filtras en la clausula WHERE por una columna del lado derecho entonces las materias sin calificaciones se filtraran bajo la condicion " NULL = '101010' " lo cual no es conocido y por tanto esas filas seran excluidas.
Lo que se ha hecho al filtrar el lado derecho en la clausula WHERE es convertir el OUTER JOIN en un INNER JOIN que no es lo que se desea.
La solucion es poner el filtro sobre el lado derecho como parte de la expresion de union.
select a.Materia,b.cal,a.semestre from @Materias a left join @calificacion b on a.id_materia=b.id_materia and b.matricula='101010'; /* Materia cal semestre Matematicas I 7.5 1 Qumica I 8 1 Fisica I 9 1 Algoritmos I 5 1 Matematicas II NULL 2 Qumica II NULL 2 Fisica II NULL 2 Algoritmos II NULL 2 */
AMB
Some guidelines for posting questions...
AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas- Marcado como respuesta Yōichi Hiruma jueves, 21 de junio de 2018 14:30
Todas las respuestas
-
Hola, estás filtrando con un where, que valor quieres que te arroje en las columnas que pones en blanco,
Votar es agradecer.
Saludos.
Lima-Perú- Editado Augusto1982 miércoles, 20 de junio de 2018 20:34
-
-
Deleted
- Marcado como respuesta Yōichi Hiruma jueves, 21 de junio de 2018 14:31
-
Hola
select b.Materia, isnull(cast(a.cal as varchar(5)),'') as cal, case when a.cal is null then '' else cast(b.semestre as varchar(1)) end as semestre from @Materias b left join @calificacion a on b.id_materia = a.id_materia or a.id_materia is null where a.matricula='101010' or a.matricula is null
Para obtenerlos todos, si filtras por a.matricula, tambien tienes que añadirle donde no tenga.
Un saludo
- Marcado como respuesta Yōichi Hiruma jueves, 21 de junio de 2018 14:30
-
El problema lo tienes en el filtro que haces en la clausula WHERE, como indica Augusto1982.
Repasemos lo que estas haciendo en base a lo que deseas para que des cuentas donde esta el problema.
Si deseas seleccionar todas las materias, independientemente de que se tenga una calificacion o no entonces necesitamos un OUTER JOIN tal como lo has hecho. Esto significa que por cada materia se mostrara la calificacion que macha en el lado derecho o en su vez se mostrara la marca NULL. Si tu filtras en la clausula WHERE por una columna del lado derecho entonces las materias sin calificaciones se filtraran bajo la condicion " NULL = '101010' " lo cual no es conocido y por tanto esas filas seran excluidas.
Lo que se ha hecho al filtrar el lado derecho en la clausula WHERE es convertir el OUTER JOIN en un INNER JOIN que no es lo que se desea.
La solucion es poner el filtro sobre el lado derecho como parte de la expresion de union.
select a.Materia,b.cal,a.semestre from @Materias a left join @calificacion b on a.id_materia=b.id_materia and b.matricula='101010'; /* Materia cal semestre Matematicas I 7.5 1 Qumica I 8 1 Fisica I 9 1 Algoritmos I 5 1 Matematicas II NULL 2 Qumica II NULL 2 Fisica II NULL 2 Algoritmos II NULL 2 */
AMB
Some guidelines for posting questions...
AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas- Marcado como respuesta Yōichi Hiruma jueves, 21 de junio de 2018 14:30
-