none
Consulta SQL RRS feed

  • Pregunta

  • Buenas tardes, tengo la siguiente consulta:

    SELECT c.CodigoBarra, p.Codigo, (p.Nombre + ' - ' + p.Medida) 'Nombre', p.PrecioContado
     from  productos_codigobarra c
     LEFT OUTER JOIN productos p ON p.idProducto=c.idProducto

    y el resultado es este:

    15000    1    VARIOS - u    0.00
    28011    1    VARIOS - u    0.00
    15001    2    AGUJA - p    238.00
    201    2    AGUJA - p    238.00
    15002    3    PALETA - p    238.00
    202    3    PALETA - p    238.00
    15003    4    OSOBUCO - p    210.00
    203    4    OSOBUCO - p    210.00
    15004    5    MOLIDA - p    248.00
    204    5    MOLIDA - p    248.00

    Yo necesito que de la tabla Codigo de Barra me traiga solo una fila por producto, no interesa cuantos codigos de barra tenga asociado ese producto.

    Alguien me ayuda?

    Saludos!!

    miércoles, 26 de agosto de 2020 22:15

Todas las respuestas

  • Hola, creo que lo único que necesitas es agrupar en base al codigo, intenta utilizando group by c.CodigoBarra.

    miércoles, 26 de agosto de 2020 22:45
  • Hola Mauricio Hamak:

    El escenario que planteas:

    create table productos_codigoBarra (idProducto int, CodigoBarra int);
    create table productos (idProducto int,codigo int, Nombre varchar(100), Medida char(1), PrecioContado money)
    go
    Insert into productos (idProducto,codigo, Nombre, Medida, PrecioContado)
    values
    (1,1,'Varios' , 'u', 0.),
    (2,2,'Aguja'  , 'p', 238.),
    (3,3,'Paleta' , 'p', 238.),
    (4,4,'Osobuco', 'p', 210.),
    (5,5,'Molida' , 'p', 248.);
    go
    Insert into productos_codigoBarra(idProducto, CodigoBarra)
    values
    (1,15000),
    (1,28011),
    (2,15001),
    (2,201),
    (3,15002),
    (3,202),
    (4,15003),
    (4,303),
    (5,15004),
    (5,204);
    go

    Para obtener una sola fila puedes hacer varias cosas.

    • Opción 1:



    SELECT min(c.CodigoBarra) as CodigoBarra
    	 , p.Codigo
    	 , p.Nombre + ' - ' + p.Medida AS 'Nombre'
    	 , p.PrecioContado
    	   from productos as p
    		INNER JOIN productos_codigobarra AS c ON p.idProducto = c.idProducto
    		group by  p.Codigo, p.Nombre , p.Medida, p.PrecioContado;

    Utilizar una función de agregación y agrupar por el resto de campos.

    Utilizar INNER JOIN si todos los productos tienen algún código de barra o left join si alguno puede no tenerlo.

    Insert into productos (idProducto,codigo, Nombre, Medida, PrecioContado)
    values
    (6,6,'Ejemplo' , 'u', 0.);
    --Con inner
    SELECT min(c.CodigoBarra) as CodigoBarra
    	 , p.Codigo
    	 , p.Nombre + ' - ' + p.Medida AS 'Nombre'
    	 , p.PrecioContado
    	   from productos as p
    		Inner JOIN productos_codigobarra AS c ON p.idProducto = c.idProducto
    		group by  p.Codigo, p.Nombre , p.Medida, p.PrecioContado;
    -- Con left
    SELECT min(c.CodigoBarra) as CodigoBarra
    	 , p.Codigo
    	 , p.Nombre + ' - ' + p.Medida AS 'Nombre'
    	 , p.PrecioContado
    	   from productos as p
    		Left JOIN productos_codigobarra AS c ON p.idProducto = c.idProducto
    		group by  p.Codigo, p.Nombre , p.Medida, p.PrecioContado;
    • Opción 2:

    Puedes utilizar el operador apply

    -- Con cross apply
    SELECT c.CodigoBarra as CodigoBarra
    	 , p.Codigo
    	 , p.Nombre + ' - ' + p.Medida AS 'Nombre'
    	 , p.PrecioContado
    	   from productos as p
    			Cross apply (
    			Select top(1) CodigoBarra From productos_codigobarra
    			where productos_codigoBarra.idProducto = p.idProducto
    			) as c
    -- Con outer apply
    SELECT c.CodigoBarra as CodigoBarra
    	 , p.Codigo
    	 , p.Nombre + ' - ' + p.Medida AS 'Nombre'
    	 , p.PrecioContado
    	   from productos as p
    		Outer apply (
    			Select top(1) CodigoBarra From productos_codigobarra
    			where productos_codigoBarra.idProducto = p.idProducto
    			) as c
    		


    La ventaja de utilizar el operador apply, es que puedes realizar una función tipo tabla y que esta lo resuelva dejando el código mucho más corto y bonito.

    Create function fn_Til_OneCodBar(@idProducto int)
    returns table
    return
    (
    	Select top(1) CodigoBarra From productos_codigobarra
    			where productos_codigoBarra.idProducto =@idProducto
    		order by CodigoBarra desc -- el operador top permite order by.
    );

    Ahora solo tenemos que invocar a la función como si fuera una tabla y le pasamos como parámetro el idCodigo de la tabla de productos.

    -- Con cross apply
    SELECT c.CodigoBarra as CodigoBarra
    	 , p.Codigo
    	 , p.Nombre + ' - ' + p.Medida AS 'Nombre'
    	 , p.PrecioContado
    	   from productos as p
    			Cross apply  dbo.fn_Til_OneCodBar(p.idProducto) as c
    -- Con outer apply
    SELECT c.CodigoBarra as CodigoBarra
    	 , p.Codigo
    	 , p.Nombre + ' - ' + p.Medida AS 'Nombre'
    	 , p.PrecioContado
    	   from productos as p
    		Outer apply dbo.fn_Til_OneCodBar(p.idProducto) as c

    Group by

    https://javifer2.wordpress.com/2019/10/04/group-by-quizas-la-clausula-mas-conflictiva/

    Operador apply

    https://javifer2.wordpress.com/2020/06/27/operador-apply/

    jueves, 27 de agosto de 2020 3:54
  • gracias Alberto
    lunes, 31 de agosto de 2020 15:53