How to sum total amount for every month in a year? - sql

I have a database in SQL Server 2012 and there is a table with dates in D.M.YYYY format like below:
ID | Date(date type) | Amount(Numeric)
1 3.4.2013 16.00
1 12.4.2013 13.00
1 2.5.2013 9.50
1 18.5.2013 10.00
I need to sum the total amount for every month in a given year. For example:
ID | Month | TotalAmount
1 1 0.00
...
1 4 29.00
1 5 19.50
I thought what I needed was to determine the number of days in a month, so I created a function which is described in determine the number of days, and it worked. After that I tried to compare two dates(date type) and got stuck; there are some examples out there, but all of them about datetime.
Is this wrong? How can I accomplish this?

I think you just want an aggregation:
select id, month(date) as "month", sum(amount) as TotalAmount
from t
where year(date) = 2013
group by id, month(date)

Related

How to calculate average monthly number of some action in some perdion in Teradata SQL?

I have table in Teradata SQL like below:
ID trans_date
------------------------
123 | 2021-01-01
887 | 2021-01-15
123 | 2021-02-10
45 | 2021-03-11
789 | 2021-10-01
45 | 2021-09-02
And I need to calculate average monthly number of transactions made by customers in a period between 2021-01-01 and 2021-09-01, so client with "ID" = 789 will not be calculated because he made transaction later.
In the first month (01) were 2 transactions
In the second month was 1 transaction
In the third month was 1 transaction
In the nineth month was 1 transactions
So the result should be (2+1+1+1) / 4 = 1.25, isn't is ?
How can I calculate it in Teradata SQL? Of course I showed you sample of my data.
SELECT ID, AVG(txns) FROM
(SELECT ID, TRUNC(trans_date,'MON') as mth, COUNT(*) as txns
FROM mytable
-- WHERE condition matches the question but likely want to
-- use end date 2021-09-30 or use mth instead of trans_date
WHERE trans_date BETWEEN date'2021-01-01' and date'2021-09-01'
GROUP BY id, mth) mth_txn
GROUP BY id;
Your logic translated to SQL:
--(2+1+1+1) / 4
SELECT id, COUNT(*) / COUNT(DISTINCT TRUNC(trans_date,'MON')) AS avg_tx
FROM mytable
WHERE trans_date BETWEEN date'2021-01-01' and date'2021-09-01'
GROUP BY id;
You should compare to Fred's answer to see which is more efficent on your data.

SQL - Repeated sum of the values, based on dates selected

Currently, I need a simple thing:
sale_date
Gross
SUM_GROSS
2018-01-01
1
6
2018-01-02
2
6
2018-01-03
3
6
I know this question already mentioned before, the difference now, is that I need to calculate a sum based on selected dates. (I use BigQuery)
SUM(SALES.GrossValueBaseCurrency) OVER(PARTITION BY ???) AS SUM_GROSS
If I will use
SUM(SALES.GrossValueBaseCurrency) OVER(PARTITION BY SALE.SALE_DATE) AS SUM_GROSS
It will give me what I would like ONLY if I will select specific ONE day.
How can I make it work, so if I will select different dates, SUM_GROSS will repeat the SUM of ALL gross values for a selected period of time?
SAMPLE DATA and Expectations:
Expecting 60 in SUM_GROSS column
Row SALE_DATE GROSS SUM_GROSS
1 25/08/2018 10.00 60
2 04/10/2018 10.00 60
3 04/07/2018 10.00 60
4 01/03/2018 10.00 60
5 10/02/2018 10.00 60
6 10/01/2018 10.00 60
If you will query this table result should be :
SELECT SUM(GROSS) AS GROSS, SUM_GROSS FROM TABLE
WHERE SALE_DATE BETWEEN 01/01/2018 AND 01/04/2018
GROUP BY SUM_GROSS
RESULT:
GROSS SUM_GROSS
30 30
I think you want conversation in partition clause:
SUM(SALES.GrossValueBaseCurrency) OVER (PARTITION BY EXTRACT(YEAR from SALE.SALE_DATE), EXTRACT(MONTH from SALE.SALE_DATE)) AS SUM_GROSS
EDIT :
SELECT . . .,
SUM(SALES.GrossValueBaseCurrency) OVER () AS SUM_GROSS
FROM SALES s
WHERE SALE.SALE_DATE BETWEEN "2018-01-01 AND "2018-02-01"
Is this what you are looking for?
SUM(CASE WHEN sales.sale_date = '2018-01-01'
THEN SALES.GrossValueBaseCurrency
ELSE 0
END) OVER () AS sales_20180101

Getting Monthly Data

I want to extract all budget entries charged to the current year and cumulated over each month after .In January, taking the total over January, February take accumulated of January plus accumulated February...
I started with this query :
IF OBJECT_ID('tempdb..#BudgetTransTmp') IS NOT NULL
DROP TABLE #BudgetTransTmp
Select
Row_number() over(ORDER BY YEAR(BTLine.DATE),MONTH(BTLine.DATE)) as RowNumber,
COMBINATION.DISPLAYVALUE,
BTLine.LedgerDimension AS LedgerDimension,
MIN(BTLine.TransactionCurrencyAmount) AS Amount,
SUM(BTLine.TransactionCurrencyAmount)
OVER (ORDER BY YEAR(BTLine.DATE),MONTH(BTLine.DATE),BTLine.LedgerDimension,COMBINATION.DISPLAYVALUE ) AS SUM,
YEAR(BTLine.DATE) AS Year ,
MONTH(BTLine.DATE) AS MONTH
INTO #BudgetTransTmp
FROM MicrosoftDynamicsAX.dbo.BudgetTransactionLine AS BTLine
--Get Display value
INNER JOIN MicrosoftDynamicsAX.dbo.DIMENSIONATTRIBUTEVALUECOMBINATION AS COMBINATION
ON COMBINATION.RECID = BTLine.LEDGERDIMENSION
GROUP BY
BTLine.LedgerDimension,
YEAR(BTLine.DATE),
MONTH(BTLine.DATE)
ORDER BY RowNumber
The result is :
LedgerDimension Amount SUM Year Month Display
1 22565448266 850.00 850.00 2012 8 601200-001-027--
2 22565448265 1700.00 2550.0 2012 12 601200-002-027--
3 22565448266 2700.00 5250.00 2012 12 601200-001-027--
4 22565448267 650.00 5900.00 2012 12 601400-002-027--
5 22565448268 1100.00 7000.00 2012 12 601400-001-027--
But i want to get
LedgerDimension Amount SUM Year Month Display
1 22565448266 850.00 850.00 2012 8 601200-001-027--
2 22565448265 1700.00 1700.0 2012 12 601200-002-027--
3 22565448266 2700.00 3350.00 2012 12 601200-001-027--
4 22565448267 650.00 650.00 2012 12 601400-002-027--
5 22565448268 1100.00 1100.00 2012 12 601400-001-027--
I think my COMBINATION of ORDER by (primary key) must be betwwen LedgerDimension ,Year , Month , Display
Any help in this regards
I think what you need to do is:
SUM(BTLine.TransactionCurrencyAmount)
OVER (PARTITION BY BTLine.LedgerDimension ORDER BY YEAR(BTLine.DATE),MONTH(BTLine.DATE),BTLine.LedgerDimension,COMBINATION.DISPLAYVALUE ) AS SUM
let me know if this works.

select column values based on other column date

I have a dataset being returned that has monthly values for different 'Goals.' The goals have unique ID's and the month/date values will always be the same for the goals. The difference is sometimes one goal doesn't have values for all the same months as the other goal because it might start at a later date, and i want to 'consolidate' the results and sum them together based on the 'First' startBalance for each goal. Example dataset would be;
goalID monthDate startBalance
1 1/1/2014 10
1 2/1/2014 15
1 3/1/2014 22
1 4/1/2014 30
2 4/1/2014 13
2 5/1/2014 29
What i want to do is display these consolidated (summed) values in a table based on the 'First' (earliest Month/Year) value for each goal. The result would look like;
Year startBalance
2014 23
This is because the 'First' value for goalID of 1 is 10 and the 'First' value for goalID of 2 is '13'
I am trying to ultimately use this dataset in an SSRS report through Report Builder, but the groupings are not working correctly for me so i figured if i could achieve this through my queries and just display the data that would be a viable solution.
An example of real result data would be
so i'd want the overall resultset to be;
Year startBalance
2014 876266.00
2015 888319.92
2016 ---------
and so on, i understand for 2015 in that result set there is a value of 0.00 for ID 71, but usually that will contain an actual dollar amount, which would automatically adjust.
WITH balances AS (
SELECT ROW_NUMBER() OVER (PARTITION BY goalID ORDER BY monthDate ASC) n, startBalance, DATEPART(year, monthDate) [year]
FROM Goals
)
SELECT [year], SUM(startBalance) startBalance
FROM balances
WHERE n = 1
GROUP BY [year]

SQL statement to generate a table of totals by month

I am very unfamiliar with advanced SQL.
Lets say I have the following table (in Access - using Jet 4.0 OLEDBAdapter in VB.NET).
Table - Items
ID Date Account Amount
----- ------ ------- ------
1 1/1/2013 Cash 10.00
2 2/1/2013 Cash 20.00
3 1/2/2013 Cash 30.00
4 2/2/2013 Cash 40.00
5 1/1/2013 Card 50.00
6 2/1/2013 Card 60.00
7 1/2/2013 Card 70.00
8 2/2/2013 Card 80.00
And I want to generate the following - totals for each account per month
Table - Totals
Account Jan Feb
----- ----- ------
Cash 30.00 70.00
Card 110.00 150.00
Is this possible using one SQL statement. I can do it in two but it is very slow.
Edit - the closest I have got is this - but it doesn't generate columns
SELECT accFrom, Sum(amount)
FROM Items
WHERE Year(idate) = '2012'
GROUP BY Month(idate), accFrom
Using your sample data, this is the output I got from the query below with Access 2010.
Account 2013-01 2013-02
------- ------- -------
Card $120.00 $140.00
Cash $40.00 $60.00
My totals don't match your expected output. I suspect your date values were d-m-yyyy format, but my US locale interpreted them as m-d-yyyy. It's better to present dates in yyyy-m-d format to avoid that confusion.
Anyway this query formats the dates as yyyy-mm, and then pivots to generate the columns for each year-month combination. So it will accommodate a growing date range without requiring you to modify the query. And, as the date range grows, you could eventually add a WHERE clause to limit to columns to a convenient subset.
TRANSFORM Sum(i.Amount) AS SumOfAmount
SELECT i.Account
FROM Items AS i
GROUP BY i.Account
PIVOT Format(i.Date,'yyyy-mm');
Since there are exactly 12 months in a year, you do not need to pivot; just calculate the sum for each month:
SELECT Account,
Sum(IIF(Month(Date)=01, Amount, 0)) AS Jan,
Sum(IIF(Month(Date)=02, Amount, 0)) AS Feb,
Sum(IIF(Month(Date)=03, Amount, 0)) AS Mar,
Sum(IIF(Month(Date)=04, Amount, 0)) AS Apr,
Sum(IIF(Month(Date)=05, Amount, 0)) AS May,
Sum(IIF(Month(Date)=06, Amount, 0)) AS Jun,
Sum(IIF(Month(Date)=07, Amount, 0)) AS Jul,
Sum(IIF(Month(Date)=08, Amount, 0)) AS Aug,
Sum(IIF(Month(Date)=09, Amount, 0)) AS Sep,
Sum(IIF(Month(Date)=10, Amount, 0)) AS Oct,
Sum(IIF(Month(Date)=11, Amount, 0)) AS Nov,
Sum(IIF(Month(Date)=12, Amount, 0)) AS "Dec"
FROM Items
WHERE Year(Date) = 2013
GROUP BY Account
Goose is right, you'll need to pivot on your Date column and use SUM() as the aggregate.
The syntax will look something similar to:
SELECT account, [1/1/2013] as jan, [2/1/2013] as feb, ... -- each month you want to select
FROM
(
SELECT date, account, amount FROM items
)
PIVOT
(
SUM(amount) FOR date IN
(
[1/1/2013], [2/1/2013], ... -- each date you want to have its own column
)
) AS pvt