Sum results values in mysql

Asked

Viewed 9,315 times

3

I am servicing a bank and am finding it difficult to make a select.

Table structure descontos_taxas:
      id | value | client | data_created

My Scenario: This table holds both rates and discounts in the same table. Rates are positive values and discounts are negative values.
I need to take all the values of all customers, however, if a customer has received a fee and a discount on the same day I need to get only one result with the difference between the two.

So far I’ve done this:

SELECT 
     *
FROM 
    descontos_taxas as dt
WHERE 
    YEAR(dt.data_criado) = 2014 and MONTH(dt.data_criado) = 04 and dt.valor < 0
GROUP BY 
    dt.data_criado, dt.cliente
ORDER BY 
    data_criado asc;

How to return only negative amounts of the result of the sum of fees and discounts applied to the same customer? (Customers who do not have fees applied on the same day of the discount the amount would be added to 0).

I have this result in select:

 valor |    cliente    | data_criado
-19,90 | Erlon Charles | 2014-04-01
  9,90 | Erlon Charles | 2014-04-01
-19,90 | Erlon Charles | 2014-04-05
-19,90 | Erlon Charles | 2014-04-19

I need this result to match this:

 valor |    cliente    | data_criado
-10,00 | Erlon Charles | 2014-04-01 //aqui estão os dados das tuplas 1 e 2 somados
-19,90 | Erlon Charles | 2014-04-05
-19,90 | Erlon Charles | 2014-04-19
  • what happens if you use the function SUM() mysql?

  • I did not get the correct value, I checked in some customers and was returned only the discount value and not the difference value. Example: a rate of 19.90 and a discount of -19.90, the select returns -19.90 when was to return 0.00.

  • Important, in the database the values are saved with a signal . Otherwise we will need to use a case, something like (case when type=’D' then value * -1 Else end value)

  • Yes values are saved with signal. I updated the question by entering an example of what I have and what I need to return.

  • It has already been done in my answer, what is your doubt another thing the id can’t even appear there !!!

  • I will still play your answer @Fccdias, was answering the question of others before testing your answer, so I check I put my considerations and if it is correct I mark, fine?

  • Sure @Erloncharles, but, my aim is not to score was to help and my concern is if you had tested ok!

  • I know, but marking how correct will help direct anyone who opens this question in the future

  • Now I don’t know to whom I mark as correct, I took the tests and I needed to use the HAVING suggested by @Acco and the sums suggested by @fccdias to solve my problem

Show 4 more comments

3 answers

5


I added having to filter after group, and separation of rates and discounts:

SELECT
    SUM( IF( valor > 0, valor, 0 ) ) AS taxas,
    SUM( IF( valor < 0, -valor, 0 ) ) AS descontos,
    SUM(valor) AS total,
    cliente,
    data_criado
FROM
    descontos_taxas
WHERE
    YEAR(data_criado) = 2014 and MONTH(data_criado) = 04
GROUP BY
    cliente, data_criado
ORDER BY
    data_criado asc
HAVING
    total < 0;
  • is data_criado even

  • in the simple way it returns me the following error Error Code: 1111. Invalid use of group function, when I will filter only the negatives.

  • Ooops, wobble my.

  • I understand the difficulty in understanding what I’m asking, I even spent a morning to get to interpret what the financier wanted in the report before trying.

  • @Erloncharles and the worst thing is that we run the risk of the financier saying "it was nothing like that" after :D But think of the bright side, if it were HR, it would be even more complicated. I’ve never seen a department more lost than HR.

  • KKKKKKKKKKKKKKKKK

  • The financier asked for a report of the discounts to all customers in a month, but some wrong applied discounts were corrected by applying an equal value rate (the system is dumb and this needed to be done)then I have to show all discounts given to customers excluding from the list the sum of discounts and rate that are 0 from the list.

  • this being that the discount and rates are in the same table being differentiated only for the discounts are negative values

  • Oh yes, then you can put the total HAVING = 0. Anyway, I added the separate sums in the query to see how it does, not need to complicate with subquery.

  • I took the test and still have one thing, customers q has discount and rate at the same value, can not enter the report, because this rate is a way to cancel the discount and vice versa, I can not show customers where the sum between rate and discount is 0, I have to show only those who are less than 0, that is, those who have real discount applied. I’m trying to do here and I’m already getting a headache.

Show 6 more comments

2

If I understood correctly it would be the Sum of Fees, the Sums of Discounts and then the Difference of the two, grouped by customer and data_created:

SELECT a.cliente, 
       a.data_criado, 
       a.taxas, 
       a.desconto,  
       (a.taxas - abs(a.desconto)) diferenca
FROM (
SELECT cliente, data_criado, 
    sum(CASE WHEN valor > 0 THEN VALOR ELSE 0 END) taxas,
    sum(CASE WHEN valor < 0 THEN VALOR ELSE 0 END) desconto
FROM descontos_taxas
GROUP BY cliente, data_criado) as a

If you still need to filter:

SELECT a.cliente, 
       a.data_criado, 
       a.taxas, 
       a.desconto,  
       (a.taxas - abs(a.desconto)) diferenca
FROM (
SELECT cliente, data_criado, 
    sum(CASE WHEN valor > 0 THEN VALOR ELSE 0 END) taxas,
    sum(CASE WHEN valor < 0 THEN VALOR ELSE 0 END) desconto
FROM descontos_taxas
GROUP BY cliente, data_criado) as a
WHERE date_format(a.data_criado, '%Y-%m') = '2014-04'

Upon request the reply

SELECT a.cliente, 
       a.data_criado, 
       (a.taxas - abs(a.desconto)) valor
FROM (
SELECT cliente, data_criado, 
    sum(CASE WHEN valor > 0 THEN VALOR ELSE 0 END) taxas,
    sum(CASE WHEN valor < 0 THEN VALOR ELSE 0 END) desconto
FROM descontos_taxas
GROUP BY cliente, data_criado) as a

1

You need to group the result by customer and by day, and need to remove the condition dt.valor < 0 query. It needs to enter as a having (which is processed after operations). See:

SELECT 
     dt.cliente, dt.data_criado, sum(valor) AS resultado
FROM 
    descontos_taxas as dt
WHERE 
    YEAR(dt.data_criacao) = 2014 and MONTH(dt.data_criacao) = 04 
GROUP BY 
    dt.cliente, DATE_FORMAT(data_criado, "%d/%m/%Y")
ORDER BY 
    data_criado asc
HAVING
    resultado < 0;

I didn’t test the query, it’s just a direction.

  • In addition to the date need also list only the negative values (related to discount)

  • 1

    @Erloncharles This does not match what you said in the question. Can you edit the question to clarify? And Arivan, considering the text of the question at this time, it seems that you just forgot to group also per customer.

  • @bfavaretto the last paragraph says so "How to return only the negative values of the result of the sum of fees and discounts applied to the same customer on the same day?"

  • @Erloncharles So I guess I just change DAY(data_criacao) for data_criacao in this answer and you get the result you want.

  • that the difference is with grouping

  • The grouping cannot be done only by "data_creation", because it can be a datetime. To ensure, better use a DATE_FORMAT() :-).

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.