S
S
SLJ2020-02-21 11:10:08
SQL
SLJ, 2020-02-21 11:10:08

How to calculate the sum of the same values ​​in one column, but different in another?

There is an operating DB under Firebird, base for sales.
There is the following request:

SELECT
        (C.CODE) AS "Табельный", (C.NAME) AS "Ф.И.О.",
        T.TRANZDATE AS "Дата", T.TRANZTIME AS "Время",
        (T.INFOSTR) AS "Карта", T.SUMM AS "Сумма"

FROM DOCUMENT D LEFT JOIN TRANZT T ON
                  D.ID = T.DOCUMENTID
                  JOIN CLIENT C ON
                  D.CLIENTID = C.ID

WHERE
      T.TRANZDATE >='20.02.2020' AND T.TRANZDATE <='20.02.2020' AND
      T.TRANZTIME >='18:55:00' AND T.TRANZTIME <='23:59:59' AND
      D.STATE = 1 AND
      (D.ISFISCAL = 1) AND
      D.CLIENTID >=0 AND
      T.TRANZTYPE = '36'

GROUP BY C.CODE, C.NAME, T.TRANZDATE, T.TRANZTIME, T.INFOSTR, T.SUMM
ORDER BY C.NAME ASC, T.TRANZDATE ASC, T.TRANZTIME ASC, T.SUMM DESC

As a result I get the following:
Таб-й      ФИО                           Дата        Время     Карта     Сумма

7 845  Иванов Иван Иванович              20.02.2020  20:17:41  1953722   12,000  
1 526  Паршуков Иоан Иванович         20.02.2020  20:17:13  1953793   20,000  
4 815  Колымин Константин Александрович  20.02.2020  20:16:54  13694802  20,000  
4 613  Сидоров Андрей Анатольевич        20.02.2020  20:18:08  1593579   12,000  
4 613  Сидоров Андрей Анатольевич        20.02.2020  20:18:38  1593579    6,000


The essence of the question: what needs to be added so that Andrey Anatolyevich Sidorov does not have two separate entries of 12 and 6, respectively, but immediately shows the sum of 18? those. it is necessary to find the same values ​​(card numbers) from the document table in the clientid column, and if there are any, then add the summ values ​​from the tranzt tables.
I can send you tables if needed.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergey Pankov, 2020-02-21
@SLJ

Remove T.TRANZTIME from the grouping and from the select. There are two different meanings.
If you definitely need to show something (for example, the last one), then throw it out of the grouping, and put an aggregator there in the select, for example, max.
This is how your Sidorov will be summed up on this dataset in one line:

SELECT
    C.CODE AS "Табельный",
    C.NAME AS "Ф.И.О.",
    T.TRANZDATE AS "Дата",
    max(T.TRANZTIME) AS "Время",
    T.INFOSTR AS "Карта",
    sum(T.SUMM) AS "Сумма"
FROM 
    DOCUMENT D
        LEFT JOIN TRANZT T ON D.ID = T.DOCUMENTID
        JOIN CLIENT C ON D.CLIENTID = C.ID
WHERE
      T.TRANZDATE >='20.02.2020' AND T.TRANZDATE <='20.02.2020' AND
      T.TRANZTIME >='18:55:00' AND T.TRANZTIME <='23:59:59' AND
      D.STATE = 1 AND
      D.ISFISCAL = 1 AND
      D.CLIENTID >=0 AND
      T.TRANZTYPE = '36'
GROUP BY
    C.CODE,
    C.NAME,
    T.TRANZDATE,
--    T.TRANZTIME,
    T.INFOSTR
--    ,T.SUMM

But your problems don't end there. There are many other bugs in your SQL:
  1. What is the point of making such a condition: T.TRANZTIME <='23:59:59'? Any time will satisfy him.
  2. If your date and time are related, that is, they define some point in time, then they need to be stored and filtered as a single value, otherwise you yourself will not notice how you will stumble upon an inconsistency error that is not obvious (for a beginner). For example, event B is later than event A, but A happened in the evening, and B in the morning (of another day). With your separate comparison of dates and times, incorrectness may result due to the fact that the time (without date) of event A > time (without date) of event B. Combine the date and time in a single datetime field or combine them every time you do conditional filtering by time range.
  3. Why are you grouping by T.SUMM if you were going to aggregate this field?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question