Select Sum in Table with PHP / Mysql

1

I have a table with the following fields: date, time and quantity . And I need to do a select sum addition.

To understand better, I have a form where I insert a date, after I insert, I will make an appointment in the bank and in it I need to return the information of how many 'qtd' it has in a certain time of the chosen date. >

Example: I need to add the entire 'qtd' field on the date 2017-06-07 to 11-00 , no longer be allowed to enter values at this time, 150 (integer).

This image illustrates well what I need to do:

I'm using PHP / mysql, but I'm having a hard time putting this logic together. Does Select Sum do this type of operation? What is the best way to do this rule?

Can anyone help me?

    
asked by anonymous 03.06.2017 / 17:30

3 answers

3

To check:

$select = "SELECT hora,COALESCE(SUM(qtd), 0) FROM table WHERE data='2017-06-07' GROUP BY hora"; //No caso coloquei a hora e data que você utilizou no seu exemplo, mas teria que ser as váriaveis que você pegou do formulário.
$comando = mysqli_query($connect, $select); //$connect é o endereço do servidor.

$count = mysqli_num_rows($comando);
if ($count > 0)
{
    while ($row=mysqli_fetch_row($comando))
    {
        printf ('Hora: %s Quantidade: %s \n', $row[0], $row[1]); //Só para fazer o teste, não necessário.
        if ($row[1] > 150)
        {
            echo "Indisponível.";
        }
        else
        {
            echo "Boa disponibilidade.";
        }
    }
}
else
{
    echo "Boa disponibilidade.";
}

To perform the update:

$select = "SELECT SUM(qtd) FROM table WHERE (data='2017-06-07' AND hora='11-00') GROUP BY hora";
$comando = mysqli_query($connect, $select);
$row = mysqli_fetch_row($comando);
if ($row[0] + $quantidade > 150)
{
    echo "Não existem tantas vagas.";
}
else
{
    $update = "UPDATE table SET qtd=qtd + '$quantidade' WHERE data='2017-06-07' AND hora='11-00'";
    mysqli_query($connect, $update);
}
    
07.06.2017 / 01:00
3

Let's suppose that your table has the following structure:

create table quantidades (
    'id' int not null auto_increment,
    'data' date,
    'hora' time,
    'quantidade' int,
    primary key (id)
);

Considering some values in the table:

insert into quantidades 
values (default, "2017-06-06", "13:00:00", 50),
       (default, "2017-06-06", "14:00:00", 60),
       (default, "2017-06-06", "15:00:00", 70),
       (default, "2017-06-06", "15:00:00", 30);

That is, the system has three registered times, each with the amounts 50, 60 and 100 (70 + 30), respectively.

To select the records, displaying the date, time and total quantity of each one just do:

select 'data', 'hora', sum('quantidade') as 'total' 
from quantidades 
group by 'data', 'hora';

In this way, the three registers will be returned:

data       | hora     | total
-----------+----------+--------
2017-06-06 | 13:00:00 | 50
2017-06-06 | 14:00:00 | 60
2017-06-06 | 15:00:00 | 100

To make the insertion of new values, ensuring that the total does not exceed 150, just do:

SET @data = "2017-06-06", @hora = "13:00:00", @quantidade = 60;
insert into quantidades ('data', 'hora', 'quantidade')
select @data, @hora, @quantidade 
    where (
        select sum('quantidade') 
        from quantidades
        where 'data' = @data and 'hora' = @hora
    ) + @quantidade  <= 150;

The first line:

SET @data = "2017-06-06", @hora = "13:00:00", @quantidade = 60;

Defines variables with values to insert into the database. These values are likely to be defined with PHP. Something like:

SET @data = "{$data}", @hora = "{$hora}", @quantidade = {$qnt};

Next, the statement of insert default, however, is not followed by values , but a select . This so that the values to be entered will only be passed from select to insert if the select condition is true. In this case, the condition is that the sum of the current total, plus the quantity to be entered, must be less than or equal to 150. If it is, the values are passed to insert , being inserted into the database. Otherwise, if the sum between the current total plus the quantity being entered exceeds 150, the record is not made.

It is important to note that, since the current total is checked before inserting a new record, the date and time must already be previously registered in the bank, because if they do not exist, the select condition is not satisfied and the record will never be made.

So, for example, when you enter an amount of 90 in 2017-06-06, 13:00:00

SET @data = "2017-06-06", @hora = "13:00:00", @quantidade = 90;
insert into quantidades ('data', 'hora', 'quantidade')
select @data, @hora, @quantidade 
    where (
        select sum('quantidade') 
        from quantidades
        where 'data' = @data and 'hora' = @hora
    ) + @quantidade  <= 150;

The registration will be done, because at this time the total amount in the bank is 50 and 90 is being inserted, totaling 140, which does not exceed 150.

data       | hora     | total
-----------+----------+--------
2017-06-06 | 13:00:00 | 140
2017-06-06 | 14:00:00 | 60
2017-06-06 | 15:00:00 | 100

However, if you try to enter the same quantity at the time 15:00:00

SET @data = "2017-06-06", @hora = "15:00:00", @quantidade = 90;
insert into quantidades ('data', 'hora', 'quantidade')
select @data, @hora, @quantidade 
    where (
        select sum('quantidade') 
        from quantidades
        where 'data' = @data and 'hora' = @hora
    ) + @quantidade  <= 150;

The registration will not be done, because at this time there is already a total of 100 and 100 + 90 exceeds the limit of 150.

data       | hora     | total
-----------+----------+--------
2017-06-06 | 13:00:00 | 140
2017-06-06 | 14:00:00 | 60
2017-06-06 | 15:00:00 | 100

A record of 50, or less, will be done as expected:

SET @data = "2017-06-06", @hora = "15:00:00", @quantidade = 50;
insert into quantidades ('data', 'hora', 'quantidade')
select @data, @hora, @quantidade 
    where (
        select sum('quantidade') 
        from quantidades
        where 'data' = @data and 'hora' = @hora
    ) + @quantidade  <= 150;

Getting into the table:

data       | hora     | total
-----------+----------+--------
2017-06-06 | 13:00:00 | 140
2017-06-06 | 14:00:00 | 60
2017-06-06 | 15:00:00 | 150
  

If you are using PDO, you can check whether the record was entered or not by checking the number of rows affected by the insert statement, using the PDOStatement::rowCount . If you returned 1, the record was entered, but if 0, the record was not entered because the total exceeded 150.

    
07.06.2017 / 01:44
2

Fiddle: link

Data Creation

CREATE TABLE registro (
    'id' INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    'data' date,
    'hora' time,
    'quantidade' int
);

INSERT INTO registro   
VALUES (null, "2017-06-06", "13:00:00", 20),
       (null, "2017-06-06", "14:00:00", 30),
       (null, "2017-06-06", "15:00:00", 90),
       (null, "2017-06-06", "15:00:00", 80),
       (null, "2017-06-05", "15:00:00", 100);

Select grouped by date and time:

SELECT data, SUBSTRING(hora, 1, 5) AS hora_minuto, SUM(quantidade) AS soma_quantidade FROM registro GROUP BY data, hora_minuto

Select grouped by specific date:

SELECT data, SUBSTRING(hora, 1, 5) AS hora_minuto, SUM(quantidade) AS soma_quantidade FROM registro WHERE data = '2017-06-06' GROUP BY data, hora_minuto

Select by specific date and time

SELECT data, SUBSTRING(hora, 1, 5) AS hora_minuto, SUM(quantidade) AS soma_quantidade FROM registro WHERE data = '2017-06-06' GROUP BY data, hora_minuto HAVING hora_minuto = '15:00'

Want to know which time has more quantities (independent of the day)?

SELECT SUBSTRING(hora, 1, 5) AS hora_minuto, SUM(quantidade) AS soma_quantidade FROM registro GROUP BY hora_minuto ORDER BY soma_quantidade DESC

Do you want to put the message in the proper return of the select? (I do not recommend)

SELECT data, SUBSTRING(hora, 1, 5) AS hora_minuto, SUM(quantidade) AS soma_quantidade, IF(SUM(quantidade) > 150, 'Indisponível', 'Boa disponibilidade') AS descricao FROM registro GROUP BY data, hora_minuto

    
07.06.2017 / 20:56