Question

I am trying to calculate running total in following query

select 
    a.ICode, MONTH(a.VDate), YEAR(a.vdate)
    , sum(isnull(a.qty, 0))
    , sum(isnull(a.qty, 0)) OVER (partition by a.icode order by a.icode) AS 'total' 
from 
    t_Stock as a
group by 
    a.ICode, MONTH(a.VDate), YEAR(a.vdate)
order by 
    a.icode, YEAR(a.vdate), MONTH(a.VDate)

but I am getting an error:

Msg 8120, Level 16, State 1, Line 3
Column 't_Stock.Qty' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Why does 't_Stock.Qty' needs to be in GROUP BY clause as I am already using aggregate function (Sum(a.Qty)) ?

Some demo data :

icode   vtype   qty   vdate 
32114   Sales   -2    2013-06-03 18:09:17.953 
33459   Sales   -1    2013-06-03 19:39:59.843 
34446   Sales   -1    2013-06-03 20:46:17.030 
39914   Tra     -3    2014-01-07 13:02:31.000
30899   Sales   -1    2013-06-04 11:48:06.267 
25676   Sales   -3    2013-06-04 17:34:01.470 
32126   Sales   -1    2013-06-04 18:12:44.267 
34688   Sales   -1    2013-06-04 18:40:52.750 
31550   Sales   -1    2013-06-04 19:26:40.937 
32795   Sales   -1    2013-06-05 12:03:00.250 
Was it helpful?

Solution

When using window functions with aggregation, you actually need to nest the results. Here is a version of your query that should work:

select a.ICode, MONTH(a.VDate), YEAR(a.vdate),
       sum(isnull(a.qty, 0)),
       sum(sum(isnull(a.qty, 0))) OVER (partition by a.icode order by a.icode) AS total
from t_Stock a
group by a.ICode, MONTH(a.VDate), YEAR(a.vdate)
order by a.icode, YEAR(a.vdate), MONTH(a.VDate);

I'm not sure what you intend to do with this. Having the order by contain the same value as the partition by is unusual. I would expect something like this:

select a.ICode, MONTH(a.VDate), YEAR(a.vdate),
       sum(isnull(a.qty, 0)),
       sum(sum(isnull(a.qty, 0))) OVER (partition by a.icode
                                        order by year(a.vdate), month(a.vdate)
                                       ) AS total
from t_Stock a
group by a.ICode, MONTH(a.VDate), YEAR(a.vdate)
order by a.icode, YEAR(a.vdate), MONTH(a.VDate);

OTHER TIPS

write as:

select a.ICode,MONTH(a.VDate), YEAR(a.vdate)
, sum(isnull(a.qty,0)) OVER(partition by a.icode order by a.icode)
  AS 'Runningtotal'
, sum(isnull(a.qty,0)) OVER(partition by a.icode,MONTH(a.VDate), YEAR(a.vdate) 
  order by a.icode,YEAR(a.vdate),MONTH(a.VDate)) AS 'total' 
from 
t_Stock as a
--group by a.ICode ,MONTH(a.VDate), YEAR(a.vdate)
order by a.icode,YEAR(a.vdate),MONTH(a.VDate)

why does 't_Stock.Qty' needs to be in GROUP BY clause as I am already using aggregate function (Sum(a.Qty)) ?

this issue appears because u use "SUM(something)" then u use "SUM(something) over(partition by...)"

when u use "SUM(something)" then you will need the "group by ..." clause but when u use "SUM(something) over(partition by...)", it doesn't accept/need a "group by.." clause http://technet.microsoft.com/en-us/library/ms189461.aspx


choose one between them.

if you want to use both of them, try below query:

select a.ICode,MONTH(a.VDate) as 'month', YEAR(a.vdate) as 'year'
, bb.xtotal
,sum(isnull(a.qty,0)) OVER (partition by a.icode order by a.icode) AS 'total' 
from 
@temp a
inner join
(
 select b.ICode, b.vdate,
    sum(isnull(b.qty,0)) as xtotal
 from @temp b 
 group by b.Icode, b.vdate
) bb on a.Icode = bb.Icode and bb.vdate = a.vdate
order by a.icode,YEAR(a.vdate),MONTH(a.VDate)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top