none
Como hacer multiples sumas en una columna de misma tabla sql - c# RRS feed

  • Pregunta

  • Tengo el siguiente problema, tengo 1 tabla en sql donde tengo la información de alumnos con el precio mensual de membresía en la biblioteca. Lo que quiero es sumar total precio en una columna Total por el nombre de la persona siempre cuando agrego nuevos datos.Los intentos con usar List> no tuvieron éxito..

    Ejemplo de la tabla y sus datos las que quiero guardar en base de datos:

    Nombre  |  Ano | Mes |Precio|Total    
    Raul    | 2018 |  1  |3.20  |3.20   
    Diego   | 2018 |  1  |3.20  |3.20    
    Maria   | 2018 |  1  |3.10  |3.10     
    Maria   | 2018 |  2  |3.10  |6.20    
    Raul    | 2018 |  2  |3.10  |6.30

    Classe registro

        public int Nombre { get; set; }
        public int Ano { get; set; }
        public decimal Precio { get; set; }   
        public decimal Total {get; set; }
    
    rg.Nombre = txtNombre.Text;
    rg.Ano = Convert.ToInt32(txtAno.Text);
    rg.Mes = Convert.ToInt32(txtMes.Text);
    rg.Precio = Convert.ToDecimal(txtPrecio.Text);
    
    
      SqlCommand cmd;
    
      string insert = "insert into Alum(Nombre,Ano,Mes,Precio,Total) 
         values(@nom,@ano,@mes,@precio,@total)";
     SELECT Nombre, Ano, sum(Precio) as Total
       FROM Alum
       GROUP BY Nombre, Ano ORDER BY Nombre COMMIT";
    cmd.CommandType = CommandType.Text;
    lunes, 7 de mayo de 2018 12:56

Todas las respuestas

  • Hola:

    Creo que estas mezclando conceptos.

    Tu string insert = "xxx......" es una consulta a priori valida para insertar un regitro, por tanto en tu variable local antes de insertar, la que supongo que pasas como paremtro de la consulta @total sera

    @total= @Precio*@Mes; antes de poner el ese string.

    Es más y veo que tienes un poco de lio.

    Voy a ver si te lo clarifico un poco.

      public class Registro
        {
            public string Nombre{ get; set; }
            public int Ano { get; set; }
            public int Mes { get; set; }
            public decimal Precio { get;set;}
            public decimal total { get; set; }
    /*defino tu modelo de registro, pero le pongo el mes que te lo has olvidado supongo */
    
    /*Constructor parametrizado */
            public Registro(string nom, int anyo, decimal precio, decimal total)
            {
                this.Nombre = nom;
                this.Ano = anyo;
                this.Precio = precio;
                this.total = total;
            }
    /*Constructor vacio */
            public Registro()
            {
            }
    
    
        }

    Ahora creo una clase para insertar. Ojo aquí se puede hacer de 1 millón de maneras, yo te expongo 1 para que puedas ir saliendo del paso e hilando un poco mejor tus requisitos.

    public class MiBBDD
        {
            private string miConexion = "Aqui mi cadena de conexion";
            public MiBBDD() //constructor
            {
    
            }
    
    /*metodo para insertar tu registro */
            public void Registrar(Registro reg)
            {
    /* Ten cuidado con los tipos de datos, porque tienes
    un poco de lio. Tienen que ser los mismos del objeto, o sino los tienes que convertir. */
                string @Nombre = reg.Nombre;
                int @Anual = reg.Ano;
                decimal @Precio = reg.Precio;
                decimal @Total = reg.total;
                decimal @Mes = reg.Mes; 
    
                using (SqlConnection conn = new SqlConnection(this.miConexion)){
                    /*Le asigamos al objeto SqlConnection la cadena de conexion que esta en el atributo string  miConexion de la clase */
                    string sql ="insert into Alum(Nombre,Ano,Mes,Precio,Total) "
                        + "values(@nom,@ano,@mes,@precio,@total)"; 
                    SqlCommand cmd = new SqlCommand(sql,conn);
                   /*Fijate en que las variables locales las he llamado diferentes a los parametros que se van al Sql */
    cmd.Parameters.AddWithValue("@nom",@Nombre);
                    cmd.Parameters.AddWithValue("@ano",@Anual);
                    cmd.Parameters.AddWithValue("@mes",@Mes);
                    cmd.Parameters.AddWithValue("@precio",@Precio);
                    cmd.Parameters.AddWithValue("@total",@Total);
    /*Ejecutamos la consulta */
                    cmd.ExecuteNonQuery();
    
    
                }
    
    
            }
        }

    Por ultimo un método donde se hace todo

      public void comoEjecuto()
            {
    /*creo un objeto registro*/
                Registro reg = new Registro();
    /*le pongo sus parametros */
                reg.Nombre = txtNombre.Text;
                reg.Ano = Convert.ToInt32(txtAno.Text);
                reg.Mes = Convert.ToInt32(txtMes.Text);
                reg.Precio = Convert.ToDecimal(txtPrecio.Text);
                reg.total = reg.Mes * reg.Precio;/* si tienes un textbox, lo sacas de el*/
                MiBBDD persistir = new MiBBDD();
    /*una vez creado mi objeto persistir, invoco a su metodo con el objeto reg, que hemos alimentado para persistirlo en la base de datos.*/
                persistir.Registrar(reg);
    
    
    
            }

    Espero te clarifique un poco tu situación

    Un saludo

    lunes, 7 de mayo de 2018 18:14
  • Si lo que no tienes es un campo total en un textbox, entonces solo es PRECIO * MES y con eso lo tienes resuelto.

    Saludos

    lunes, 7 de mayo de 2018 18:15
  • Muchas gracias por su respuesta. Lo que necesito es sumar total precio en una columna Total por el nombre de la persona siempre que agrego nuevos datos y no necesito  hacer : mes*precio.
    lunes, 7 de mayo de 2018 21:45
  • Hola amigo.

    quisas esto le funcione.

    Esto hace lo siguiente.

    Supongamos que tengo la columna total en mi gridview, esa columna  tiene los siguientes datos.

    TOTAL

      12

      30

      40

    el codigo hace recorrer el grid y mostrarme el precio total de la suma (12 + 30 + 40) en un  label.

        void SUMAPRECIOS()
            {
                int suma = 0;
                for(int i=0;i< TABLAEQUIPOS.Rows.Count; i++)
                {
                    int precio = Convert.ToInt32(TABLAEQUIPOS.Rows[i]["TOTAL"].ToString());
                    suma = suma + precio;
                }
                Label5.Text = suma.ToString();

            }

    lunes, 7 de mayo de 2018 23:57
  • Ustando codigos en esta manera me pone un cero en columna Total.. Lo nocesito que columna total sera determinada por el nombre y que sume el precio cada nombre en columna total. Seguro que hago algo mal con estos codigos. 

    void SUMAPRECIOS()
                {
                    decimal suma = 0;
                    for (int i = 0; i <= suma; i++)
                    {
                        reg.Precio = Convert.ToDecimal(txtPrecio.Text);

                        suma = suma + reg.Precio;
                    }
                    reg.Total = suma;

                }

                        
    martes, 8 de mayo de 2018 13:06
  • Entiendo entonces que tu tienes la tabla

    Nombre  |  Ano | Mes |Precio|Total    
    Raul    | 2018 |  1  |3.20  |3.20   
    Diego   | 2018 |  1  |3.20  |3.20    
    Maria   | 2018 |  1  |3.10  |3.10     
    Maria   | 2018 |  2  |3.10  |6.20    
    Raul    | 2018 |  2  |3.10  |6.30

    Pero lo que quieres es tener siempre que insertes un registro a Raul en la columna total lo que llevase hasta ese momento, por ejemplo 6.30 y sumase lo que llegue, imaginando que

    Raul nuevo registro 2018, 3, 800 por tanto Total tiene que tener 806.30 en esa fila.

    Así de este modo cuando leas la última fila de Raúl, ya sabes su total. Sin calcular nada.

    Saludos

    martes, 8 de mayo de 2018 13:45
  • Exactamente eso es lo que necesito. Por haora tengo problemas con sumar dentro de la tabla en base dedatos SQL. Usando los codigos de ariba no hace cosa como quiero. Ustedes muchas gracias con intentos de ayudarme..
    martes, 8 de mayo de 2018 14:20
  • Vale, así lo puedes hacer, te voy a poner todas las capas.

    En base de datos, la definicion de una tabla de ejemplo como la tuya y un procedimiento almacenado, (método más seguro y fiable, para trabajar con datos, que las consultas en un string).

    CREATE TABLE ALUM(ID INT PRIMARY KEY IDENTITY (1,1),NOMBRE VARCHAR(100), ANO INT, MES INT, PRECIO FLOAT, TOTAL FLOAT)
    GO
    
    
    CREATE PROCEDURE INSERTAR_ALUM (@NOMBRE VARCHAR(100), @ANYO INT, @MES INT, @PRECIO FLOAT)
    AS
    BEGIN TRY
    BEGIN TRAN
    	 INSERT INTO ALUM (NOMBRE, ANO, MES, PRECIO, TOTAL) 
    	 VALUES(@NOMBRE, @ANYO, @MES, @PRECIO, (
    			SELECT TOP(1) TOTAL+@PRECIO FROM ALUM WHERE NOMBRE = @NOMBRE
    			ORDER BY ID DESC  )/* EL VALOR ULTIMO DE EL REGISTRO DE ESTE USUARIO + LO QUE LE TOCA PAGAR ESTE MES*/
    		)
    	COMMIT TRAN
    END TRY
    BEGIN CATCH
    	ROLLBACK TRAN
    	PRINT 'HA OCURRIDO UNA EXCEPCION, DEBES DE TRATARLA, PUEDES USAR THROW O RAISERROR'
    END CATCH
    

    El objeto registro

    public class Registro
        {
            public string Nombre { get; set; }
            public int Ano { get; set; }
            public int Mes { get; set; }
            public decimal Precio { get; set; }
            
            /*defino tu modelo de registro, pero le pongo el mes que te lo has olvidado supongo */
    
            /*Constructor parametrizado */
            public Registro(string nom, int anyo, int mes, decimal precio, decimal total)
            {
                this.Nombre = nom;
                this.Ano = anyo;
                this.Mes = mes;
                this.Precio = precio;
            
            }
            /*Constructor vacio */
            public Registro()
            {
            }
    
    
        }


    Metodo para registrar el base de datos

     public void Registrar(Registro reg)
            {
                string @Nombre = reg.Nombre;
                int @Anual = reg.Ano;
                int @mes = reg.Mes;
                decimal @Precio = reg.Precio;
                /*recogemos en variables los valores del objeto recibido */
    
                /* aqui dispongo mi conexion a la base de datos */
                var ConnectionString = @"Password=" + bdpassword + @";Persist Security Info=True;User ID="
                    + @bdusuario + @";Initial Catalog=" + bdbasedatos + ";Data Source=" + bdservidor + ";";
    
                    SqlConnection connection = new SqlConnection(ConnectionString);
                    try
                    {
                        connection.Open();
                        SqlCommand Query = new SqlCommand("INSERTAR_ALUM", connection);
    /* indicamos el procedimiento almacenado */
                        Query.Parameters.Add("@NOMBRE", System.Data.SqlDbType.VarChar, 100).Value = @Nombre;
                        Query.Parameters.Add("@ANYO", System.Data.SqlDbType.Int).Value = @Anual;
                        Query.Parameters.Add("@MES", System.Data.SqlDbType.Int).Value = @mes;
                        Query.Parameters.Add("@PRECIO", System.Data.SqlDbType.Float).Value = @Precio;
                        
                        Query.CommandType = CommandType.StoredProcedure;
    
                        Query.ExecuteNonQuery();
    
                    }
                    catch (SqlException e){
                        /*tramaiento de excepciones que consideres oportuno*/
                        throw new Exception("Problemas con: "+e.Message);
                    }
                    finally
                    {
                        connection.Close();
                    }
                }

    Desde mi Form con 4 textbox.

          private void button1_Click(object sender, EventArgs e)
            {
                try
                {
    /*Creacion de objeto para dialogar con la base de datos */
                    IntegracionBaseDatos integra = new IntegracionBaseDatos(server, bd, user, pass);
    
                    try
                    {
    /* genero un objeto en memoria */
                        Registro reg = new Registro();
                        reg.Nombre = textBoxNombre.Text;
                        reg.Ano = Convert.ToInt32(textBoxAnual.Text);
                        reg.Mes = Convert.ToInt16(textBoxMes.Text);
                        reg.Precio = Convert.ToDecimal(textBoxPrecio.Text);
    /*Una vez convertidos y asignados los valores */
                        integra.Registrar(reg); /* invocacion de la persistencia */
                    }
                    catch { }
    
                }
                catch { }
    
    
            }

    Un saludo

    martes, 8 de mayo de 2018 16:25