Multiple select against one table in one query - sql

I'm trying to construct a select statement that will give me a percentage value for each month and user.
I have a table with rows that looks like this;
Table name: pytrans
tTransDate tArtCode tTime tSignature
20120801 DKK 1 30JK
20120801 AD 1.5 30JK
20120802 DKB 3 40AK
20120903 MI 2 45TR
20120904 DKK 2 30JK
20120904 DKB 2 30JK
The select(s) should give me the percentage of how much time spent on tArtCode DKB or DKK for each signature and month of all time spent on all tArtCode. So from the above example the select should give me 40% for signature 30JK in month 8 and 100% for signature 30JK in month 9.
I have tried different kind of sql select statements but It doesn’t seem to get 100% right.
This is what I’ve got;
select DATEPART(YY, tTransdatum) AS Year, DATEPART(mm, tTransdatum) AS Month, tSignatur,
(select SUM(tAntal) AS SumPart from pytrans where tSignatur = '30JK' AND (tArtikelkod = 'DKK' OR tArtikelkod = 'DKB'))
/(select DATEPART(YY, tTransdatum) AS Year, DATEPART(mm, tTransdatum) AS Month, SUM(tAntal) AS SumTot from pytrans where tSignatur = '30JK' GROUP BY Year, Month, SumTot) * 100
From pytrans where tSignatur = '30JK' GROUP BY DATEPART(mm, tTransdatum), DATEPART(YY, tTransdatum), tSignatur
This SQL don’t work the error is that I can’t group Year, Month, SumTot. Also i get error; Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
This next sql select give me what i want but I’m to specific what I’m asking for... so to speak. If I use this sql i then need to have a sql query for every signature and every month, and that’s not really creative.
select TOP 1 DATEPART(YY, tTransdatum) AS Year, DATEPART(mm, tTransdatum) AS Month, tSignatur,
SumProc = (select SUM(tAntal) from pytrans
where tSignatur = '30JK' AND (tArtikelkod NOT LIKE 'FL' AND tArtikelkod NOT LIKE 'SEM' AND tArtikelkod NOT LIKE 'KOMPIN') AND (tArtikelkod = 'DKK' OR tArtikelkod = 'DKB') AND tTransdatum BETWEEN '20121101' AND '20121131')
/ (select SUM(tAntal) from pytrans
where tSignatur = '30JK' AND (tArtikelkod NOT LIKE 'FL' AND tArtikelkod NOT LIKE 'SEM' AND tArtikelkod NOT LIKE 'KOMPIN') AND tTransdatum BETWEEN '20121101' AND '20121131') * 100
from pytrans
Where tSignatur = '30JK' AND tTransdatum BETWEEN '20121101' AND '20121131'
group by tTransdatum, tSignatur
I’ve also tried Union but that doesn’t seem to work for me.
I really need help with this! Thanks!

Create Table #pytrans(tTransdatum datetime, tArtCode varchar(10), tAntal float, tSignature varchar(10))
insert into #pytrans Values('20120801', 'DKK', 1 ,'30JK')
insert into #pytrans Values('20120801', 'AD', 1.5 ,'30JK')
insert into #pytrans Values('20120802', 'DKB', 3 ,'40AK')
insert into #pytrans Values('20120903', 'MI', 2 ,'45TR')
insert into #pytrans Values('20120904', 'DKK', 2 ,'30JK')
insert into #pytrans Values('20120904', 'DKB', 2 ,'30JK')
Select a.Year,a.Month,a.tSignature,a.SumPart as aAll,b.SumPart as bAll,Case when b.SumPart =0 then NULL else a.SumPart/b.SumPart * 100 end as [Percent]
from
(select DATEPART(YY, tTransdatum) AS Year, DATEPART(mm, tTransdatum) AS Month, tSignature
,SUM(tAntal) AS SumPart
from #pytrans
where tSignature = '30JK' AND tArtCode in( 'DKK' ,'DKB')
Group by DATEPART(YY, tTransdatum) , DATEPART(mm, tTransdatum) , tSignature) a
Left Join
(select DATEPART(YY, tTransdatum) AS Year, DATEPART(mm, tTransdatum) AS Month, tSignature
,SUM(tAntal) AS SumPart
from #pytrans
where tSignature = '30JK'
Group by DATEPART(YY, tTransdatum) , DATEPART(mm, tTransdatum) , tSignature) b
on a.Month=b.Month and a.Year =b.Year and a.tSignature = b.tSignature

Related

Percentage difference from previous year

Trying to add a percent difference column to my data as i'm showing the last 3 years of sales and commissions in my query and want percent of difference for each salesperson listed to show the difference in the amounts that were made for sales and also for commission from the previous year in that same month. So for the amount made in January 2017 for commission and sales, I want to show whether they had an increase or decrease in the amount between what was earned in January 2018 compared to what was earned in January 2017.
SELECT TOP (100) PERCENT
'ABC' AS CompanyCode,
ABC.AR_Salesperson.SalespersonName,
ABC.AR_SalespersonCommission.SalespersonDivisionNo,
ABC.AR_SalespersonCommission.SalespersonNo,
SUM(ABC.AR_SalespersonCommission.InvoiceTotal) AS InvoiceTotalSum,
SUM(ABC.AR_SalespersonCommission.CommissionAmt) AS CommissionAmtSum,
DATENAME(month, ABC.AR_SalespersonCommission.InvoiceDate) AS Month,
DATENAME(year, ABC.AR_SalespersonCommission.InvoiceDate) AS Year,
DATEPART(m, ABC.AR_SalespersonCommission.InvoiceDate) AS MonthNumber
FROM
ABC.AR_Customer INNER JOIN
ABC.AR_SalespersonCommission ON
ABC.AR_Customer.ARDivisionNo = ABC.AR_SalespersonCommission.ARDivisionNo AND
ABC.AR_Customer.CustomerNo = ABC.AR_SalespersonCommission.CustomerNo INNER JOIN
ABC.AR_Salesperson ON
ABC.AR_SalespersonCommission.SalespersonDivisionNo = ABC.AR_Salesperson.SalespersonDivisionNo AND
ABC.AR_SalespersonCommission.SalespersonNo = ABC.AR_Salesperson.SalespersonNo
GROUP BY
ABC.AR_Salesperson.SalespersonName,
ABC.AR_SalespersonCommission.SalespersonDivisionNo,
ABC.AR_SalespersonCommission.SalespersonNo,
DATENAME(month, ABC.AR_SalespersonCommission.InvoiceDate),
DATENAME(year, ABC.AR_SalespersonCommission.InvoiceDate),
DATEPART(m, ABC.AR_SalespersonCommission.InvoiceDate)
HAVING
(DATENAME(year, ABC.AR_SalespersonCommission.InvoiceDate) > DATEADD(year, - 4, GETDATE()))
ORDER BY
SalespersonName,
Year,
MonthNumber
Tried various ways to get the data to do this but haven't been able to, like using OVER PARTITION BY and all that. Desired Results and Sample Data are in the link below.
You can use a CTE and JOIN to it using the previous year:
; WITH L4Y
AS (SELECT TOP (100) PERCENT
'ABC' AS CompanyCode,
ABC.AR_Salesperson.SalespersonName,
ABC.AR_SalespersonCommission.SalespersonDivisionNo,
ABC.AR_SalespersonCommission.SalespersonNo,
SUM(ABC.AR_SalespersonCommission.InvoiceTotal) AS InvoiceTotalSum,
SUM(ABC.AR_SalespersonCommission.CommissionAmt) AS CommissionAmtSum,
DATENAME(month, ABC.AR_SalespersonCommission.InvoiceDate) AS Month,
DATENAME(year, ABC.AR_SalespersonCommission.InvoiceDate) AS Year,
DATEPART(m, ABC.AR_SalespersonCommission.InvoiceDate) AS MonthNumber
FROM
ABC.AR_Customer INNER JOIN
ABC.AR_SalespersonCommission ON
ABC.AR_Customer.ARDivisionNo = ABC.AR_SalespersonCommission.ARDivisionNo AND
ABC.AR_Customer.CustomerNo = ABC.AR_SalespersonCommission.CustomerNo INNER JOIN
ABC.AR_Salesperson ON
ABC.AR_SalespersonCommission.SalespersonDivisionNo = ABC.AR_Salesperson.SalespersonDivisionNo AND
ABC.AR_SalespersonCommission.SalespersonNo = ABC.AR_Salesperson.SalespersonNo
GROUP BY
ABC.AR_Salesperson.SalespersonName,
ABC.AR_SalespersonCommission.SalespersonDivisionNo,
ABC.AR_SalespersonCommission.SalespersonNo,
DATENAME(month, ABC.AR_SalespersonCommission.InvoiceDate),
DATENAME(year, ABC.AR_SalespersonCommission.InvoiceDate),
DATEPART(m, ABC.AR_SalespersonCommission.InvoiceDate)
HAVING
(DATENAME(year, ABC.AR_SalespersonCommission.InvoiceDate) > DATEADD(year, - 4, GETDATE()))
)
SELECT L4Y.*
, InvoiceTotalPrevYear = COALESCE(LY.InvoiceTotalSum, 0)
, CommissionAmtSumPrevYear = COALESCE(LY.CommissionAmtSum, 0)
FROM L4Y
LEFT JOIN L4Y LY
ON L4Y.CompanyCode = LY.CompanyCode
AND L4Y.SalespersonName = LY.SalespersonName
--...(join on ALL fields except YEAR)
AND l4y.[Month] = LY.[Month]
-- Here's where the magic happens:
AND L4Y.[Year] = (LY.[Year]-1) ;

Running Totals for the year

Trying to create running totals based on the year in my query as i'm showing the last 3 years of sales and commissions in my query and want running yearly totals for those for each salesperson listed
Tried various ways to get the data to do this but haven't been able to.
SELECT TOP (100) PERCENT 'abc' AS CompanyCode, abc.AR_Salesperson.SalespersonName, abc.AR_SalespersonCommission.SalespersonDivisionNo, abc.AR_SalespersonCommission.SalespersonNo,
SUM(abc.AR_SalespersonCommission.InvoiceTotal) AS InvoiceTotalSum, SUM(abc.AR_SalespersonCommission.CommissionAmt) AS CommissionAmtSum, DATENAME(month, abc.AR_SalespersonCommission.InvoiceDate)
AS Month, DATENAME(year, abc.AR_SalespersonCommission.InvoiceDate) AS Year, DATEPART(m, abc.AR_SalespersonCommission.InvoiceDate) AS MonthNumber
FROM abc.AR_Customer INNER JOIN
abc.AR_SalespersonCommission ON abc.AR_Customer.ARDivisionNo = abc.AR_SalespersonCommission.ARDivisionNo AND abc.AR_Customer.CustomerNo = abc.AR_SalespersonCommission.CustomerNo INNER JOIN
abc.AR_Salesperson ON abc.AR_SalespersonCommission.SalespersonDivisionNo = abc.AR_Salesperson.SalespersonDivisionNo AND
abc.AR_SalespersonCommission.SalespersonNo = abc.AR_Salesperson.SalespersonNo
GROUP BY abc.AR_Salesperson.SalespersonName, abc.AR_SalespersonCommission.SalespersonDivisionNo, abc.AR_SalespersonCommission.SalespersonNo, DATENAME(month, abc.AR_SalespersonCommission.InvoiceDate),
DATENAME(year, abc.AR_SalespersonCommission.InvoiceDate), DATEPART(m, abc.AR_SalespersonCommission.InvoiceDate)
HAVING (DATENAME(year, abc.AR_SalespersonCommission.InvoiceDate) > DATEADD(year, - 3, GETDATE()))
UNION
SELECT TOP (100) PERCENT 'XYZ' AS CompanyCode, xyz.AR_Salesperson.SalespersonName, xyz.AR_SalespersonCommission.SalespersonDivisionNo, xyz.AR_SalespersonCommission.SalespersonNo,
SUM(xyz.AR_SalespersonCommission.InvoiceTotal) AS InvoiceTotalSum, SUM(xyz.AR_SalespersonCommission.CommissionAmt) AS CommissionAmtSum, DATENAME(month, xyz.AR_SalespersonCommission.InvoiceDate)
AS Month, DATENAME(year, xyz.AR_SalespersonCommission.InvoiceDate) AS Year, DATEPART(m, xyz.AR_SalespersonCommission.InvoiceDate) AS MonthNumber
FROM xyz.AR_Customer INNER JOIN
xyz.AR_SalespersonCommission ON xyz.AR_Customer.ARDivisionNo = xyz.AR_SalespersonCommission.ARDivisionNo AND xyz.AR_Customer.CustomerNo = xyz.AR_SalespersonCommission.CustomerNo INNER JOIN
xyz.AR_Salesperson ON xyz.AR_SalespersonCommission.SalespersonDivisionNo = xyz.AR_Salesperson.SalespersonDivisionNo AND
xyz.AR_SalespersonCommission.SalespersonNo = xyz.AR_Salesperson.SalespersonNo
GROUP BY xyz.AR_Salesperson.SalespersonName, xyz.AR_SalespersonCommission.SalespersonDivisionNo, xyz.AR_SalespersonCommission.SalespersonNo, DATENAME(month, xyz.AR_SalespersonCommission.InvoiceDate),
DATENAME(year, xyz.AR_SalespersonCommission.InvoiceDate), DATEPART(m, xyz.AR_SalespersonCommission.InvoiceDate)
HAVING (DATENAME(year, xyz.AR_SalespersonCommission.InvoiceDate) > DATEADD(year, - 3, GETDATE()))
I expect the output to have running totals for the InvoiceTotalSum and CommissionAmt for each salesperson for the last 3 years. So of course January will be 0 for each person but Feb through December will have a running total
Sample data and desired results below. Desired results are the highlighted columns
Sample Data and Desired Results
2 things before I go to the solution.
First, I am not sure why you need an UNION into your query. I can see the difference between abc and xyz but it still looks strange.
It is surely possible your query can be shortened/simplified, which would need more info to tell.
Second, I do not see a valid reason why the running total should be 0 for January.
Explanation about that:
February (2nd month of the year): running total in your expected result contains the amount for 2 months
March: 3 months
April: 4 months
...
So January should contain the running total for 1 month (January itself).
Try the query below:
WITH MyData AS (
<Please paste your query here>
)
SELECT CompanyCode, SalesPersonName, SalesPersonDivisionNo, InvoiceTotalSum,
SUM(InvoiceTotalSum) OVER (PARTITION BY SalesPersonDivisionNo, SalesPersonNo, SalesPersonName, Year ORDER BY MonthNumber) AS InvoiceTotalRunningSum,
CommissionAmtSum,
SUM(CommissionAmtSum) OVER (PARTITION BY SalesPersonDivisionNo, SalesPersonNo, SalesPersonName, Year ORDER BY MonthNumber) AS CommissionAmtRunningSum,
Month, Year, MonthNumber
FROM MyData
ORDER BY CompanyCode, SalesPersonDivisionNo, SalesPersonNo, SalesPersonName, Year, MonthNumber
The magic takes place in the PARTION BY/ORDER BY
I think you need to review your query and simplify it.
a few notes :
if the CompanyCode is already existed within the database, join its table and link it with the current records instead of writing it manually.
DATENAME(year, ... ) the shorthand is YEAR()
DATEPART(m, ...) the shorthand is MONTH()
I encourage you to use aliases
(DATENAME(year, xyz.AR_SalespersonCommission.InvoiceDate) > DATEADD(year, - 3, GETDATE())) will exclude the first year and include the current.So, 2019-3 = 2016, yours will get 2017,2018, and 2019, while it should get 2016,2017, and 2018.
for your InvoiceTotalRunningSum use :
SUM(InvoiceTotalSum) OVER (PARTITION BY SalespersonNo ORDER BY MonthNumber UNBOUNDED PRECEDING)
this will do an accumulative sum on InvoiceTotalSum for each SalespersonNo. you can partition the records for each year, month ..etc. simply by adding more partitions, but I used your current query as sub-query, and did that instead :
read more about SELECT - OVER Clause (Transact-SQL)
try it out :
SELECT
'abc' AS CompanyCode
, SalespersonName
, SalespersonDivisionNo
, SalespersonNo
, InvoiceTotalSum
, SUM(InvoiceTotalSum) OVER (PARTITION BY SalespersonNo ORDER BY MonthNumber UNBOUNDED PRECEDING) InvoiceTotalRunningSum
, CommissionAmtSum
, SUM(CommissionAmtSum) OVER (PARTITION BY SalespersonNo ORDER BY MonthNumber UNBOUNDED PRECEDING) CommissionAmtRunningSum
, [Month]
, [Year]
, MonthNumber
FROM (
SELECT
'abc' AS CompanyCode
, ars.SalespersonName
, arsc.SalespersonDivisionNo
, arsc.SalespersonNo
, SUM(arsc.InvoiceTotal) InvoiceTotalSum
, SUM(arsc.CommissionAmt) CommissionAmtSum
, DATENAME(month, arsc.InvoiceDate) [Month]
, YEAR(arsc.InvoiceDate) [Year]
, MONTH(arsc.InvoiceDate) MonthNumber
FROM
abc.AR_Customer arc
INNER JOIN abc.AR_SalespersonCommission arsc ON arc.ARDivisionNo = arsc.ARDivisionNo AND arc.CustomerNo = arsc.CustomerNo
INNER JOIN abc.AR_Salesperson ars ON arsc.SalespersonDivisionNo = ars.SalespersonDivisionNo AND arsc.SalespersonNo = ars.SalespersonNo
GROUP BY
ars.SalespersonName
, arsc.SalespersonDivisionNo
, arsc.SalespersonNo
, YEAR(arsc.InvoiceDate)
, MONTH(arsc.InvoiceDate)
, DATENAME(month, arsc.InvoiceDate)
HAVING
YEAR(arsc.InvoiceDate) BETWEEN YEAR(GETDATE()) - 3 AND YEAR(GETDATE()) - 1 -- Only include the last three years (excluding current year)
) D

How to merge sql query with union into one query

I would like to get the results of the below query with just one query not by using union.
My query is as below
I am generating a SSRS chart this query, so need to merge the query into one and get a proper result as shown in table 2
select
res.Count, res.Month, res.status, res.SortOrder
from
(SELECT
count(analysis_complete_date) as Count,
DATENAME(month, analysis_complete_date) AS Month,
DATEPART(month, analysis_complete_date) AS SortOrder,
'Analysis' as status
FROM
SCN_Part_Details AS parts
WHERE
analysis_complete_date BETWEEN '2014-01-01' AND '2014-12-11'
GROUP BY
DATENAME(month, analysis_complete_date),
DATEPART(month, analysis_complete_date)
union
SELECT
count(Act_Supp_Negotiation_Date) as Count,
DATENAME(month, Act_Supp_Negotiation_Date) AS Month,
DATEPART(month, Act_Supp_Negotiation_Date) AS SortOrder,
'Negotiated' as status
FROM
SCN_Part_Details AS parts
WHERE
Act_Supp_Negotiation_Date BETWEEN '2014-01-01' AND '2014-12-11'
GROUP BY
DATENAME(month, Act_Supp_Negotiation_Date),
DATEPART(month, Act_Supp_Negotiation_Date) ) as res
order by
res.SortOrder
This will give a result like:
Table 1
Count Month Status SortOrder
--------------------------------------------------
167 January Analysis 1
631 January Negotiated 1
70 February Analysis 2
237 February Negotiated 2
and so on..
I want a result like this:
Table 2
AnalysisCount NegotiatedCount Month SortOrder
---------------------------------------------------------
167 631 January 1
70 237 February 2
Give it a try:
;WITH CTEResult AS
(
select
res.Count, res.Month, res.status, res.SortOrder
from
(SELECT
count(analysis_complete_date) as Count,
DATENAME(month, analysis_complete_date) AS Month,
DATEPART(month, analysis_complete_date) AS SortOrder,
'Analysis' as status
FROM
SCN_Part_Details AS parts
WHERE
analysis_complete_date BETWEEN '2014-01-01' AND '2014-12-11'
GROUP BY
DATENAME(month, analysis_complete_date),
DATEPART(month, analysis_complete_date)
union
SELECT
count(Act_Supp_Negotiation_Date) as Count,
DATENAME(month, Act_Supp_Negotiation_Date) AS Month,
DATEPART(month, Act_Supp_Negotiation_Date) AS SortOrder,
'Negotiated' as status
FROM
SCN_Part_Details AS parts
WHERE
Act_Supp_Negotiation_Date BETWEEN '2014-01-01' AND '2014-12-11'
GROUP BY
DATENAME(month, Act_Supp_Negotiation_Date),
DATEPART(month, Act_Supp_Negotiation_Date) ) as res
)
SELECT DISTINCT
(SELECT TOP 1 Count FROM CTEResult A WHERE A.Month = C.Month AND A.STATUS = 'Analysis' AND A.SortOrder = C.SortOrder) AS AnalysisCount,
(SELECT TOP 1 Count FROM CTEResult B WHERE B.Month = C.Month AND B.STATUS = 'Negotiated' AND B.SortOrder = C.SortOrder) AS
NegotiatedCount, C.Month, C.SortOrder
FROM CTEResult C
Once you got your result, you can pivot the table to get the desired result.
create table #temp
(
quantity int,
month varchar(20),
status varchar(20),
sortorder int
)
insert into #temp values
(167,'January' ,'Analysis', 1 ),
(631,'January' ,'Negotiated',1 ),
(70 ,'February','Analysis', 2 ),
(237,'February','Negotiated', 2 )
select max(analysis) as analysiscount
,max(negotiated) as negotiatedcount
,month
,max(sortorder) as sortorder
from
(
select *
from #temp
pivot
(max(quantity) for status in ([analysis],[negotiated])) as pi
) t
group by month
order by sortorder;

SQL Query to sum by month

i have the two tables, Payment Table and Person Table, a person por month can have more than one payment, so i want so sum all "amount" fields from a parson per month and per year, if there is no payment the result should be 0 and ID of the person should appear in the month.
i am almost there, but in my curreny query the data displayed is all payments per person and not the sum. how can o het this?
current results are like this (see october) i need to sum below 3 payments and olny show one line of october 2013:
My Table
MonthNr---MonthAbr---Amount---PersonID---YearAmount
1---JAN---0---2---2013
2---FEB---0---2---2013
3---MAR---0---2---2013
4---APR---0---2---2013
5---MAY---0---2---2013
6---JUN---0---2---2013
7---JUL---0---2---2013
8---AUG---0---2---2013
9---SEP---0---2---2013
10---OCT---64,74---2---2013
10---OCT---73,66---2---2013
10---OCT---24,3---2---2013
11---NOV---24,3---2---2013
12----DEC----0---2----2013
My query:
SELECT
months.monthno as MonthNr,
CAST(CASE WHEN CAST(months.monthno AS int) =1 THEN 'JAN'
WHEN CAST(months.monthno AS int) =2 THEN 'FEB'
WHEN CAST(months.monthno AS int) =3 THEN 'MAR'
WHEN CAST(months.monthno AS int) =4 THEN 'APR'
WHEN CAST(months.monthno AS int) =5 THEN 'MAY'
WHEN CAST(months.monthno AS int) =6 THEN 'JUN'
WHEN CAST(months.monthno AS int) =7 THEN 'JUL'
WHEN CAST(months.monthno AS int) =8 THEN 'AUG'
WHEN CAST(months.monthno AS int) =9 THEN 'SEP'
WHEN CAST(months.monthno AS int) =10 THEN 'OCT'
WHEN CAST(months.monthno AS int) =11 THEN 'NOV'
WHEN CAST(months.monthno AS int) =12 THEN 'DEC'
ELSE
''
END AS nvarchar) as MonthAbr,
Amount = isnull(sum(o.Amount),0),
c.IDPerson as PersonID,
isnull(year(o.Date ),2013) as YearAmount
FROM
Person c
cross join
(select number monthNo from master..spt_values where type='p' and number between 1 and 12) months
full join Payments o
ON o.IDPerson = c.IDPerson
AND month(o.Date ) = months.monthNo
where c.IDPerson = 2
GROUP BY
months.monthno, c.IDPerson ,o.Date
ORDER BY
months.monthno, c.IDPerson
can anyone help me?
thanks in advance.
Since you are using the isnull function on o.date I assume this means there are nulls in this column. If so, you need to account for this within your group by clause, e.g. "group by months.monthno, c.idperson, isnull(year(o.date),2013)".
You shouldn't group by o.Date, but only by the month of the date, which you already have included as months.monthno.
Why dont you simplify it:
select
months.monthno as MonthNr
,case when monthno='1' then 'JAN'
when monthno='2' then 'FEB'
end as MonthAbr
isnull(year(o.Date ),2013) as YearAmount
,sum(Amount)
from PERSONS c
left join Payments o ON o.IDPerson = c.IDPerson
left join
(select number monthNo from master..spt_values where type='p' and number between 1 and 12) months on months.number= select month(o.Date)
group by months.monthno, o.date

How to query for a value from the last month of each quarter?

SELECT YEAR(aum.AUM_Timeperiod) as Year,
DATEPART(q, aum.AUM_TimePeriod) AS Quarter,
SUM(cast(aum.AUM_AssetValue AS money)) as total_AssetValue
FROM AssetUnderManagement as aum,
LineOfBusiness
where aum.LOB_ID = LineOfBusiness.LOB_ID
and LineOfBusiness.LOB_Name = 'Asset Management'
GROUP BY YEAR(aum.AUM_Timeperiod), DATEPART(q, aum.AUM_TimePeriod);
The above query returns the value per quarter.
My question is how to change it if I want the Total_AssetValue of the last month in that quarter to be assigned to that quarter.
For eaxmple Quater 3 total_AssetValue is sum(100+200+300). but i want the quater 3 value to be 300 which is the last month value in that quater
How about:
SELECT
Year,
Quarter,
(
SELECT SUM(CAST(AUM_AssetValue AS MONEY))
FROM AssetUnderManagement
WHERE YEAR(AUM_Timeperiod) = i.Year
AND MONTH(AUM_TimePeriod) = i.LastMonthInQuarter
) AS total_AssetValue
FROM
(
SELECT
YEAR(aum.AUM_Timeperiod) AS Year,
DATEPART(q, aum.AUM_TimePeriod) AS Quarter,
MAX(MONTH(aum.AUM_TimePeriod)) AS LastMonthInQuarter
FROM
AssetUnderManagement as aum, LineOfBusiness
WHERE
aum.LOB_ID = LineOfBusiness.LOB_ID
AND LineOfBusiness.LOB_Name = 'Asset Management'
GROUP BY
YEAR(aum.AUM_Timeperiod),
DATEPART(q, aum.AUM_TimePeriod)
) AS i
Here's a version that uses a common table expression:
WITH MyData AS
(SELECT YEAR(aum.AUM_Timeperiod) AS [Year], DATEPART(q, aum.AUM_TimePeriod) AS [Quarter],
DATEPART(M, aum.AUM_TimePeriod) AS [Month],
DATEPART(M, aum.AUM_TimePeriod) - (DATEPART(q, aum.AUM_TimePeriod) - 1) * 3 AS [MonthInQtr],
SUM(CAST(aum.AUM_AssetValue AS MONEY)) AS [total_AssetValue]
FROM AssetUnderManagement AS aum, LineOfBusiness
WHERE aum.LOB_ID = LineOfBusiness.LOB_ID
AND LineOfBusiness.LOB_Name = 'Asset Management'
GROUP BY YEAR(aum.AUM_Timeperiod), DATEPART(q, aum.AUM_TimePeriod),
DATEPART(M, aum.AUM_TimePeriod), DATEPART(M, aum.AUM_TimePeriod) -
(DATEPART(q, aum.AUM_TimePeriod) - 1) * 3
)
SELECT [Year], [Quarter]
FROM MyData
WHERE MonthInQtr = 3
ORDER BY [Year], [Quarter], [total_AssetValue]
;
You can use the same CTE from above and use the following query to get your original results
SELECT [Year], [Quarter], SUM([total_AssetValue])
FROM MyData
GROUP BY [Year], [Quarter]
ORDER BY [Year], [Quarter]
;