none
Consulta a SQL SELECT Max de un campo RRS feed

  • Pregunta

  • Buenas tardes a todos, anduve buscando en Internet, pero no logro hallar respuesta a lo siguiente. Necesito una consulta que me devuelva en un DGV un UNICO registro que indique de la tabla Pedidos, El Nº del PEDIDO y el último Nº de ITEM de dicho pedido.

    O sea, si el pedido fuese el Nº 1000 y tiene 5 Ítems relacionados, me muestre solo en la columna Pedido del DGV el 1000 y en la Columna Ítem el 5.

    Como dato aleatorio, a la consulta le paso como parámetro de búsqueda el Nº del pedido desde un Textbox y el Código del Proveedor desde un Combobox. Esto es porque pudiera ser que coincidan Nº de Pedido e Ítem  de diferentes proveedores.

    De hecho con la siguiente consulta logro llenar el DGV, pero me carga TODOS los ítems del pedido referido en el TextBox y no solo el ultimo, que es lo que deseo.

                    ConsultaSelect =

    "SELECT Pedido_Nro,Items FROM "& Tabla & " WHERE "& Col & " LIKE "& Trim(Me.txtOtPedidoNro.Text) & " AND CodProveedor= "& Val(Me.CmbIdProv.Text)

    (Tabla y Col, son variables que utilizo según determinadas situaciones)

    Se que tendría que usar un Select Max solo para el campo Ítem, pero no doy en la tecla. Desde ya, muchas gracias a quien pueda darme una mano.


    jueves, 1 de septiembre de 2016 23:07

Respuestas

  • CEB_ROJO,

    Hay algo que no me queda claro, ¿la tabla 'Pedidos' contiene también los ítems?, es decir, ¿tienes la siguiente estructura?:

    Ped 001     Item1
    Ped 001     Item2
    Ped 001     Item3
    -----------------------------
    Ped 002     Item1
    Ped 002     Item2

    De ser así, pienso que tienes un serio problema con la normalización de tablas, lo adecuado es que tengas las tablas 'CabeceraPedido' y  'DetallesPedido', en la primera tabla contienes los datos de la cabecera del pedido (número, cliente, fecha, etc) y en la segunda tabla contienes los ítems del pedido (producto, cantidad, precio).

    Veamos como sería la consulta sql para el primer caso:

    SELECT 
        Pedido_Nro, 
        COUNT(*) AS 'Items' 
    FROM 
        Pedido
    WHERE 
        Pedido_Nro = 'Valor' 
        AND CodProveedor = 'Valor' 
    GROUP BY 
        Pedido_Nro;

    Por otro lado, en tu desarrollo de acceso a datos debes evitar concatenar los valores de parámetro a la consulta:

    Dim ConsultaSelect As String = String.Format("SELECT Pedido_Nro, Items FROM {0} WHERE " &
                    "Pedido_Nro = @Pedido_Nro And CodProveedor = @CodProveedor", Tabla)
    
    'Agregar valores a los parámetros
    cmd.Parameters.AddWithValue("@Pedido_Nro", txtOtPedidoNro.Text)
    cmd.Parameters.AddWithValue("@CodProveedor", CmbIdProv.Text)
    



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta CEB_ROJO viernes, 2 de septiembre de 2016 12:35
    jueves, 1 de septiembre de 2016 23:50
  • Hola CEB_ROJO,

    [-] .. De hecho con la siguiente consulta logro llenar el DGV, pero me carga TODOS los ítems del pedido referido en el TextBox y no solo el ultimo, que es lo que deseo.

    Pero si ya tienes la consulta correctamente, sólo toma el valor mediante el SELECT TOP 1 y ordénalos en forma DESC para que el último pase al inicio.

    Además debería usar el String.Format para evitar estar concatenando de esa manera.

    ConsultaSelect = String.Format("SELECT TOP 1 Pedido_Nro, Items 
                                   FROM {0} 
                                   WHERE {1} LIKE {2} AND CodProveedor = {3} 
                                   ORDER BY Pedido_Nro DESC",
                                   tabla, Col, Trim(Me.txtOtPedidoNro.Text), Val(Me.CmbIdProv.Text))


    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    • Marcado como respuesta CEB_ROJO viernes, 2 de septiembre de 2016 12:35
    jueves, 1 de septiembre de 2016 23:50

Todas las respuestas

  • Hola CEB_ROJO,

    [-] .. De hecho con la siguiente consulta logro llenar el DGV, pero me carga TODOS los ítems del pedido referido en el TextBox y no solo el ultimo, que es lo que deseo.

    Pero si ya tienes la consulta correctamente, sólo toma el valor mediante el SELECT TOP 1 y ordénalos en forma DESC para que el último pase al inicio.

    Además debería usar el String.Format para evitar estar concatenando de esa manera.

    ConsultaSelect = String.Format("SELECT TOP 1 Pedido_Nro, Items 
                                   FROM {0} 
                                   WHERE {1} LIKE {2} AND CodProveedor = {3} 
                                   ORDER BY Pedido_Nro DESC",
                                   tabla, Col, Trim(Me.txtOtPedidoNro.Text), Val(Me.CmbIdProv.Text))


    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    • Marcado como respuesta CEB_ROJO viernes, 2 de septiembre de 2016 12:35
    jueves, 1 de septiembre de 2016 23:50
  • CEB_ROJO,

    Hay algo que no me queda claro, ¿la tabla 'Pedidos' contiene también los ítems?, es decir, ¿tienes la siguiente estructura?:

    Ped 001     Item1
    Ped 001     Item2
    Ped 001     Item3
    -----------------------------
    Ped 002     Item1
    Ped 002     Item2

    De ser así, pienso que tienes un serio problema con la normalización de tablas, lo adecuado es que tengas las tablas 'CabeceraPedido' y  'DetallesPedido', en la primera tabla contienes los datos de la cabecera del pedido (número, cliente, fecha, etc) y en la segunda tabla contienes los ítems del pedido (producto, cantidad, precio).

    Veamos como sería la consulta sql para el primer caso:

    SELECT 
        Pedido_Nro, 
        COUNT(*) AS 'Items' 
    FROM 
        Pedido
    WHERE 
        Pedido_Nro = 'Valor' 
        AND CodProveedor = 'Valor' 
    GROUP BY 
        Pedido_Nro;

    Por otro lado, en tu desarrollo de acceso a datos debes evitar concatenar los valores de parámetro a la consulta:

    Dim ConsultaSelect As String = String.Format("SELECT Pedido_Nro, Items FROM {0} WHERE " &
                    "Pedido_Nro = @Pedido_Nro And CodProveedor = @CodProveedor", Tabla)
    
    'Agregar valores a los parámetros
    cmd.Parameters.AddWithValue("@Pedido_Nro", txtOtPedidoNro.Text)
    cmd.Parameters.AddWithValue("@CodProveedor", CmbIdProv.Text)
    



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta CEB_ROJO viernes, 2 de septiembre de 2016 12:35
    jueves, 1 de septiembre de 2016 23:50
  • Muchísimas gracias por la pronta respuesta. Probaré a ver que como funciona.

    Abrazo grande.

    viernes, 2 de septiembre de 2016 13:12
  • Al igual que a Joel, muchísimas gracias por responder tan atentamente.

    Abrazo grande Willams.

    viernes, 2 de septiembre de 2016 13:14
  • Hola Joel, ahí estuve probando y funciona, pero me trae al DGV Todos los registros y yo apunto a que solo me muestre ÚNICAMENTE el registro que tenga el Nº de Ítem mas alto. O sea en el DGV solo debe aparecer un Registro cumpliendo la condición que te menciono. No se si esto se puede...

    Abrazo.

    CEB_ROJO


    viernes, 2 de septiembre de 2016 19:15
  • No es posible que recuperes mas de una fila porque la consulta que te propone Joel limita los resultados a 1 (TOP (1)). ¿Has seguido los lineamientos propuestos en la consulta?

    Por otro lado, la propuesta que te hice llegar es errada, entendí mal tu requerimiento, supuse necesitabas la cuenta de ítems para el pedido seleccionado, sin embargo, ahora que leo bien tu requerimiento la consulta de selección puede ser simple:

    SELECT MAX(Pedido_Nro), MAX(Item) FROM T WHERE Pedido_Nro = @Valor1 AND CodProveedor= @Valor2

    Entendiendo que la columna 'Item' contiene la secuencia de los items para el pedido.

    Por otro lado, noto que usas el operador LIKE sin comodines, eso no tiene sentido, necesitas un operador de comparación (=).


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    viernes, 2 de septiembre de 2016 21:21
  • Hola Willlams, disculpa la demora en responder, pasa que no estuve estos días acà

    Ok, ahora voy a ver que hice mal, creo haberlo hecho tal cual, pero bueno, seguramente me he equivocado en algo.

    De todos modos muchísimas gracias por responder y verè que equivoque. Abrazo

    domingo, 4 de septiembre de 2016 21:58