问题
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
回答1:
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);
回答2:
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)
回答3:
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)
来源:https://stackoverflow.com/questions/23443555/sql-server-running-total-with-over-partition