none
Obtener Registros que no están en otra tabla con Join RRS feed

  • Pregunta

  • Hola chicos buen día espero estén del todo bien. Tengo una duda sobre una consulta que he logrado resolver pero no se si es la forma adecuada de resolverlo.

    Tengo dos tabla, la primera se llama Movimientos y la otra se llama Productos, de modo que cada vez que se hace un movimiento se involucra un producto, entonces quiero saber que productos no se han utilizado en Movimientos. Lo he resuelto con la siguiente query:

    select DISTINCT  p.CCODIGOPRODUCTO,P.CNOMBREPRODUCTO,P.CIDVALORCLASIFICACION3,C.CVALORCLASIFICACION from Productos P 
    WHERE P.CIDPRODUCTO NOT IN(SELECT CIDPRODUCTO FROM admMovimientos) 
    

    Sin embargo he leido que puedo resolverlo con un left o righ join, sin embargo no me regresan esa información, incluso lo he intentado con left outer join y tampoco. Gracias por su ayuda.

    Saludos

    domingo, 23 de agosto de 2020 20:19

Todas las respuestas

  • Hola, podrías hacerlo con Left join como te han comentado

    CREATE TABLE #PRODUCTO
    (
     CIDPRODUCTO			INT PRIMARY KEY,
     CCODIGOPRODUCTO        VARCHAR(10),
     CNOMBREPRODUCTO        VARCHAR(30),
     CIDVALORCLASIFICACION3 VARCHAR(20),
     CVALORCLASIFICACION	VARCHAR(40)
     )
    
     CREATE TABLE #ADMMOVIMIENTOS
    (
      CIDMOVIMIENTOS INT PRIMARY KEY,
      CIDPRODUCTO INT,
      CMOVIMIENTO VARCHAR(40)
       FOREIGN KEY (CIDPRODUCTO) REFERENCES #PRODUCTO(CIDPRODUCTO)
    )
    
    INSERT INTO #PRODUCTO(CIDPRODUCTO,CCODIGOPRODUCTO,CNOMBREPRODUCTO,CIDVALORCLASIFICACION3,CVALORCLASIFICACION)
    VALUES(1,'P01','PRODUCTO 1','C01','VALOR1')
    INSERT INTO #PRODUCTO(CIDPRODUCTO,CCODIGOPRODUCTO,CNOMBREPRODUCTO,CIDVALORCLASIFICACION3,CVALORCLASIFICACION)
    VALUES(2,'P02','PRODUCTO 2','C02','VALOR2')
    INSERT INTO #PRODUCTO(CIDPRODUCTO,CCODIGOPRODUCTO,CNOMBREPRODUCTO,CIDVALORCLASIFICACION3,CVALORCLASIFICACION)
    VALUES(3,'P03','PRODUCTO 3','C03','VALOR3')
    INSERT INTO #PRODUCTO(CIDPRODUCTO,CCODIGOPRODUCTO,CNOMBREPRODUCTO,CIDVALORCLASIFICACION3,CVALORCLASIFICACION)
    VALUES(4,'P04','PRODUCTO 4','C04','VALOR4')
    
    INSERT INTO #ADMMOVIMIENTOS(CIDMOVIMIENTOS,CIDPRODUCTO,CMOVIMIENTO)VALUES(1,1,'MOVIMIENTO 1')
    INSERT INTO #ADMMOVIMIENTOS(CIDMOVIMIENTOS,CIDPRODUCTO,CMOVIMIENTO)VALUES(2,2,'MOVIMIENTO 2')
    INSERT INTO #ADMMOVIMIENTOS(CIDMOVIMIENTOS,CIDPRODUCTO,CMOVIMIENTO)VALUES(3,3,'MOVIMIENTO 3')
    
    
    SELECT P.CIDPRODUCTO,P.CCODIGOPRODUCTO,P.CNOMBREPRODUCTO
    FROM #PRODUCTO P
    LEFT JOIN #ADMMOVIMIENTOS M
    ON P.CIDPRODUCTO=M.CIDPRODUCTO
    WHERE M.CIDPRODUCTO IS NULL
    
    DROP TABLE #PRODUCTO
    DROP TABLE #ADMMOVIMIENTOS

    aquí hay un poco de teoría que explica el uso del is null en el where

    Teoría de conjuntos en MySQL con select join

    SQL Server Joins


    Votar y marcar respuestas es agradecer.
    Saludos.
    Lima-Perú

    lunes, 24 de agosto de 2020 3:02
  •  lo he intentado con left outer join y tampoco

    El truco es que tienes que hacer un left outer join (o simplemente left join, que es lo mismo) y luego filtrar con un WHERE para quedarte solo con los campos que han devuelto NULL en la tabla de la derecha (es decir, los que no se han podio unir al hacer el join).

    El compañero Augusto ya te ha puesto un ejemplo de cómo hacer esto. Pero lo que yo quería señalar es que no merece la pena que te preocupes por ello. En versiones muy antiguas de servidores de bases de datos era más eficiente hacer el JOIN que usar la cláusula NOT IN como hiciste tú en tu pregunta. Pero en todas las versiones modernas, de lo mismo. El optimizador de consultas es lo bastante inteligente para traducir las dos variantes (con NOT IN o con LEFT JOIN) de tal manera que generan exactamente el mismo plan de ejecución. Así que las dos modalidades son completamente equivalentes en cuanto a rendimiento. Por lo tanto, lo mejor es que uses aquella variante que te resulte más clara al leerla, o más simple al escribirla. Yo en general prefiero la versión con NOT IN porque me parece que proporciona una idea más clara de cuál es el propósito que se pretende lograr con esa sentencia, por lo que resulta más clara al leerla. Pero si te gusta más hacerlo con el JOIN, da lo mismo; funcionará exactamente igual de bien.

    lunes, 24 de agosto de 2020 13:40