Manera eficiente para seleccionar los registros que faltan en la otra tabla

Tengo 3 tablas. A continuación se encuentra la estructura:

  • student (id int, name varchar(20))
  • course (course_id int, subject varchar(10))
  • student_course (st_id int, course_id int) -> contiene el nombre de los estudiantes que se matricularon en un curso

Ahora, quiero escribir una consulta para averiguar los estudiantes que no se matriculan para cualquier curso. Como he podido averiguar hay varias formas de obtención de esta información. Podría usted por favor hágamelo saber cual de estos es el más eficiente y también, por qué. También, si no podría ser de cualquier otra manera mejor de la ejecución de la misma, por favor hágamelo saber.

db2 => select distinct name from student inner join student_course on id not in (select st_id from student_course)

db2 => select name from student minus (select name from student inner join student_course on id=st_id)

db2 => select name from student where id not in (select st_id from student_course)

Gracias de antemano!!

  • No sé por qué te gustaría frase como «unirse vs normal» – en mi experiencia, la mayoría de las consultas contienen al menos uno. Dicho esto, yo no usaría su primer ejemplo, ya que no es realmente el uso de una combinación en cualquier cuerdo de la moda (Un left join, por otro lado, sería una pena que la inclusión en la lista). Pero la mayoría de las preguntas acerca de la eficiencia en SQL tienden a más descender a los índices disponibles y no hacer nada demasiado extraño (como su primera consulta)
  • Gracias por su respuesta Damien!! Estoy de acuerdo con la primera consulta, en realidad es demasiado extraño y prácticamente no tiene ningún sentido…yo solo estaba tratando de explorar las opciones.
InformationsquelleAutor neha | 2013-06-29

4 Kommentare

  1. 9

    Las subconsultas que utilice, si es not in, minus o lo que sea, son generalmente ineficientes. Forma más común de hacer esto es left join:

    select name 
    from student 
    left join student_course on id = st_id
    where st_id is NULL

    Utilizando join es «normal» y preferente solución.

  2. 1

    La canónica (tal vez incluso sinópticos) modismo es (en mi humilde opinión) para el uso de NOT EXISTS :

    SELECT *
    FROM student st
    WHERE NOT EXISTS (
      SELECT *
      FROM student_course
      WHERE st.id = nx.st_id
      );

    Ventajas:

    • NOT EXISTS(...) es muy antigua, y la mayoría de los optimizadores de saber cómo manejar
    • por lo que probablemente va a estar presente en todas las plataformas
    • la nx. nombre de correlación no es filtró en la consulta externa: el select * en la consulta externa sólo el rendimiento de los campos de la student tabla, y no de la (nula) a las filas de la student_course tabla, como en el LEFT JOIN ... WHERE ... IS NULL caso. Esto es especialmente útil en las consultas con un gran número de rango de las entradas de la tabla.
    • (NOT) IN es propensa a errores (Nulos), y que podría realizar malo en algunas implementaciones (duplicados y los Nulos tienen que ser retirados a partir del resultado de la correlación subconsulta)
  3. 0

    El uso de «no» es generalmente lento. Que hace que tu segunda consulta, el más eficaz. Probablemente usted no necesita los soportes, aunque.

    • ¿Qué te hace pensar que not in es lento y minus no? Yo diría que ambos son lentos
    • Podría por favor explicar cómo unirse a es mejor que ‘no’ y ‘menos’ en este caso?
  4. 0

    Sólo como un comentario: yo sugeriría para seleccionar el Id de estudiante (que es único) y no los nombres.

    Como otra opción de consulta que usted podría desear para unir las dos tablas, grupo por student_id, count(course_id) having count(course_id) = 0.

    También, estoy de acuerdo en que los índices más importantes.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea