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
Related
For each of the 12 months, I'm looking to create a field that sums the sales dollars at the account level for the most recent month and the 2nd most recent month based on the current date.
For example, given that today's date is 2022-10-28, 'MostRecentNovember' would sum up sales from November 2021. '2ndMostRecentNovember' would sum up sales from November 2020. Once the current date moves into November 2022, this query would adjust to pull MostRecentNovember sales from 2022 and 2ndMostRecentNovember sales from 2021.
Conversely, given that today's date is 2022-10-28 'MostRecentJune' would sum up sales from June 2022 and '2ndMostRecentJune' would sum up sales from June 2021.
In the end state, each account would have 24 fields: January - December for Most Recent and January - December for 2nd most recent
Below is my attempt at this code, this gets partially there, but it's not getting what I need. I've also tried with a CTE, but that didn't seem to do it either
SELECT NovemberMostRecent_Value =
sum(case when datepart(year,tran_date) = datepart(year, getdate())
AND DATEPART(month, tran_date) = 11 then value else 0 end)
NovemberSecondMostRecent_Value =
sum(case when datepart(year,tran_date) = datepart(year, getdate())-1
AND DATEPART(month, tran_date) = 11 then value else 0 end)
Here's a snippet of the source data table
account_no
tran_date
value
123
2021-11-22
500
123
2021-11-01
500
123
2020-11-20
1500
123
2022-06-03
5000
123
2021-06-04
2000
456
2020-11-03
525
456
2021-11-04
125
A table of desired Results
account_no
NovemberMostRecent
November2ndMostRecent
June MostRecent
June2ndMostRecent
123
1000
1500
5000
2000
456
125
525
0
0
We use dense_rank() by year desc (partitioned by month) and pivot.
select *
from
(
select account_no
,value
,concat(datename(month, tran_date), '_', dense_rank() over(partition by month(tran_date) order by year(tran_date) desc)) as month_rnk
from t
) t
pivot (sum(value) for month_rnk in(June_1, June_2, November_1, November_2)) p
account_no
June_1
June_2
November_1
November_2
123
5000
2000
1000
1500
456
null
null
125
525
Fiddle
If I work at a grocery store and need to make orders for inventory, we make orders multiple times a month rather than one large order.
Item
ETA
QTY
Apples
5/6/21
10
Apples
6/12/21
15
Apples
6/30/21
10
Bananas
6/12/21
15
Bananas
7/5/21
20
Cereal
5/15/21
10
Cereal
5/30/21
50
Cereal
7/15/21
20
Is there a way to create a table that sums the QTY, if the item is the same and if the ETA month is the same to know how much of each Item is expected to arrive in a given month?
Ideally, the result I'm looking for is something that looks like this
Item
May
June
July
Apples
10
25
0
Bananas
0
15
20
Cereal
60
0
20
I would need the code to first check to see what month the item is expected to arrive in, and then if there are more than one lines that have the same item and ETA month, SUM the QTY.
I have tried doing CASE WHEN statements but always end up with syntax errors
SELECT
CASE WHEN ETA BETWEEN '2021-05-01' AND '2021-05-31'
AND WHERE Item IN
(SELECT Item
FROM ['Inventory']
GROUP BY Item HAVING COUNT(*)>1)
THEN SUM(QTY)
END AS MAY_QTY
FROM [dbo].['Inventory'];
You just use conditional aggregation:
select item,
sum(case when month(eta) = 5 then qty else 0 end) as may,
sum(case when month(eta) = 6 then qty else 0 end) as jun,
sum(case when month(eta) = 7 then qty else 0 end) as jul
from inventory i
group by item;
I would caution you that using months without a year may lead to problems. That is also true of using unsupported software -- SQL Server 2008 is no longer supported.
First you should group the data by item and month, and then use pivot to convert rows to columns.
select
item,
isnull(may,0) as May,
isnull(june,0) as June,
isnull(july,0) as July
from
(
select item, datename(month, ETA) as _month, sum(qty) as qty
from Inventory
group by item, datename(month, ETA)
) d
pivot
(
sum(qty)
for _month in (may, june, july)
) piv;
I have an SQL View Name dbo.financialactuals
ACCTNAME Month Balance Acctctgry Year Description
sales 1 344.78 income 2018 revenueAX
sales 2 2744.78 income 2018 ProduceAX
sales 3 8745.78 income 2018 annualAx
INTEREST INC 1 7866 Interest 2018 ProduceAX
INTEREST INC 2 766 Interest 2018 CTGAX3
sales 5 744.78 other 2018 AX
I tried to sum balance by AcctName But it still showing the same result. I think it's because of the description column. So, I removed the description from the select statement but it's acting same.
SELECT AcctName,
SUM(Balance) AS Balance,
AcctCtrgry,
Year,
FROM dbo.financialactuals
GROUP BY AcctName, Acctctrgy, Year,
I need an output like this.
AcctNAme Balance AcctCtrgy Year
sales -3089.56 income 2018
INTEREST INC 9632 InterestINC 2018
As it was said already in the comments this should give the requested result.
SELECT AcctName,
SUM(Balance) AS Balance,
AcctCtrgry,
Year,
FROM dbo.financialactuals
GROUP BY AcctName, Acctctrgy, Year
But the sum on the sales will be -11835.34 not -3089.56.
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]
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)