tablas - inner join en sql
¿Cómo obtener datos coincidentes de otra tabla SQL para dos columnas diferentes: Inner Join y/o Union? (3)
Tengo dos tablas en MS Access que hacen un seguimiento de los facilitadores de la clase y las clases que facilitan. Las dos tablas están estructuradas de la siguiente manera:
tbl_facilitators
facilID -> a unique autonumber to keep track of individual teachers
facilLname -> the Last name of the facilitator
facilFname -> the First name of the facilitator
tbl_facilitatorClasses
classID -> a unique autonumber to keep track of individual classes
className -> the name of the class (science, math, etc)
primeFacil -> the facilID from the first table of a teacher who is primary facilitator
secondFacil -> the facilID from the first table of another teacher who is backup facilitator
No puedo descifrar cómo escribir una unión interna que muestra los resultados en este formato:
Column 1: Class Name
Column 2: Primary Facilitator''s Last Name
Column 3: Primary Facilitator''s First Name
Column 4: Secondary Facilitator''s Last Name
Column 5: Secondary Facilitator''s First Name
Puedo detenerme y obtener los resultados correctos si solo solicito el facilitador principal por sí mismo o solo solicito el facilitador secundario por sí mismo. Sin embargo, no puedo hacer que ambos trabajen.
Esta es mi unión interna de trabajo:
SELECT tbl_facilitatorClasses.className,
tbl_facilitators.facilLname, tbl_facilitators.facilFname
FROM tbl_facilitatorClasses
INNER JOIN tbl_facilitators
ON tbl_facilitatorClasses.primeFacil = tbl_facilitators.facilID;
Por desesperación también probé una Unión, pero no funcionó como esperaba. Tu ayuda es muy apreciada. Realmente estoy luchando por hacer algún progreso en este punto. No suelo trabajar con SQL.
SOLUCIÓN
Gracias a @philipxy se me ocurrió la siguiente consulta que terminó funcionando:
SELECT tblCLS.className,
tblP.facilLname, tblP.facilFname, tblS.facilLname, tblS.facilFname
FROM (tbl_facilitatorClasses AS tblCLS
INNER JOIN tbl_facilitators AS tblP
ON tblCLS.primeFacil=tblP.facilID)
INNER JOIN tbl_facilitators AS tblS
ON tblCLS.secondFacil=tblS.facilID;
Al realizar uniones internas múltiples en MS Access, se necesitan paréntesis ... Como se describe en esta otra publicación.
Lo haría como se ve arriba al unirme a la tabla tbl_facilitators dos veces, pero es posible que desee asegurarse de que cada clase realmente requiera un segundo facilitador ya que la segunda unión debería ser una combinación externa. De hecho, podría ser más seguro suponer que no es un campo obligatorio.
Simplemente haga una unión extra para el facilitador secundario (¡y use alias de tabla!):
SELECT fc.className, f1.facilLname, f2.facilFname
FROM tbl_facilitatorClasses fc
INNER JOIN tbl_facilitators f1 ON fc.primeFacil = f1.facilID
INNER JOIN tbl_facilitators f2 ON fc.secondFacil = f2.facilID;
Cada tabla base tiene una plantilla de declaración, también conocida como predicado , parametrizada por nombres de columna, mediante la cual colocamos una fila o la dejamos afuera. Podemos usar una abreviatura para el predicado que es como su declaración de SQL.
// facilitator [facilID] is named [facilFname] [facilLname]
facilitator(facilID,facilLname,facilFname)
// class [classID] named [className] has prime [primeFacil] & backup [secondFacil]
class(classID,className,primeFacil,secondFacil)
Al conectar una fila en un predicado, se obtiene una proposición, también conocida como proposición . Las filas que hacen que una proposición verdadera entre en una tabla y las filas que hacen una proposición falsa permanecen fuera. (Entonces, una tabla indica la proposición de cada fila presente y NO establece la proposición de cada fila ausente).
// facilitator f1 is named Jane Doe
facilitator(f1,''Jane'',''Doe'')
// class c1 named CSC101 has prime f1 & backup f8
class(c1,''CSC101'',f1,f8)
Pero cada valor de expresión de tabla tiene un predicado por su expresión. SQL está diseñado para que si las tablas T
y U
contienen las filas (sin NULL-libre de duplicados) donde T (...) y U (...) (respectivamente):
-
T CROSS JOIN U
tiene filas donde T (...) Y U (...) -
T INNER JOIN U ON
condition
contiene filas donde T (...) Y U (...) AND condición -
T LEFT JOIN U ON
condition
T LEFT JOIN U ON
mantiene las filas donde (para U-only columnas U1, ...)
T (...) Y U (...) Y condición
O T (...) Y NO (U (...) Y condición ) Y U1 ES NULO Y ... -
T WHERE
condition
contiene filas donde T (...) AND condición -
T INTERSECT U
mantiene las filas donde T (...) Y U (...) -
T UNION U
mantiene filas donde T (...) O U (...) -
T EXCEPT U
mantiene filas donde T (...) Y NO U (...) -
SELECT DISTINCT * FROM T
mantiene las filas donde T (...) -
SELECT DISTINCT
columns to keep
SELECT DISTINCT
columns to keep
FROM T
contiene filas donde
EXISTE columnas para tirar TAN QUE T (...) -
VALUES (C1, C2, ...)((
v1
,
v2
, ...), ...)
contiene filas donde
C1 = v1 Y C2 = v2 Y ... O ...
También:
-
(...) IN T
significa T (...) -
scalar
= T
significa T ( escalar ) - T (..., X, ...) Y X = Y significa T (..., Y, ...) Y X = Y
Por lo tanto, para consultar encontramos una forma de redactar el predicado para las filas que queremos en lenguaje natural utilizando predicados de tabla base, luego en taquigrafía usando predicados de tabla base, luego en SQL usando nombres de tabla base (más las condiciones donde sea necesario). Si necesitamos mencionar una tabla dos veces, le damos alias.
// natural language
THERE EXISTS classID,primeFacil,secondFacil SUCH THAT
class [classID] named [className] has prime [primeFacil] & backup [secondFacil]
AND facilitator [primeFacil] is named [pf.facilFname] [pf.facilLname]
AND facilitator [secondFacil] is named [sf.facilFname] [sf.facilLname]
// shorthand
THERE EXISTS classID,primeFacil,secondFacil SUCH THAT
class(classID,className,primeFacil,secondFacil)
AND facilitator(pf.facilID,pf.facilLname,pf.facilFname)
AND pf.facilID = primeFacil
AND facilitator(sf.facilID,sf.facilLname,sf.facilFname)
AND sf.facilID = secondFacil
// table names & (MS Access) SQL
SELECT className,pf.facilLname,pf.facilFname,sf.facilLname,sf.facilFname
FROM (class JOIN facilitator AS pf ON pf.facilID = primeFacil)
JOIN facilitator AS sf ON sf.facilID = secondFacil
OUTER JOIN se usaría cuando una clase no siempre tenga ambos facilitadores o algo no siempre tenga todos los nombres. (Es decir, si una columna puede ser NULL). Pero no ha dado los predicados específicos para su tabla base y consulta o las reglas comerciales sobre cuándo las cosas podrían ser NULL, por lo que no asumí NULL.
(Los paréntesis de Re MS Access JOIN lo ven de SO y esto de MS ).