views:

510

answers:

3

Suppose i have this table

table (a,b,c,d). Datatypes are not important.

I want to do this

select a as a1,b as b1,c as c1,
       (select sum(d) from table where a=a1 and b=b1) as total
from table
group by a,b,c

...but I can't find a way (sqldeveloper keeps complaining with "from clause not found".)

Is there a way? Is it possible?

+7  A: 
SELECT  a as a1,b as b1,c as c1,
        (
        SELECT  SUM(d)
        FROM    mytable mi
        WHERE   mi.a = mo.a
                AND mi.b= mo.b
        ) as total
FROM    mytable
GROUP BY
        a, b, c

It's much more simple and efficient to rewrite it as this:

SELECT  a AS a1, B AS b1, c AS c1, SUM(SUM(d)) OVER (PARTITION BY a, b) AS total
FROM    mytable
GROUP BY
        a, b,

Note the SUM(SUM(d)) here.

The innermost SUM is the aggregate function. It calculates the SUM(d) a-b-c-wise.

The outermost SUM is the analytic function. It sums the precalculated SUM(d)'s a-b-wise, and returns the value along with each row.

Quassnoi
+2  A: 

Du you mean something like this?

select a as a1,
       b as b1,
       c as c1,
       sum(sum(d)) OVER (PARTITION BY a, b) AS total
from table
group by a,b,c
Maximilian Mayerl
What does "OVER (PARTITION BY a, b)" buy you? Doesn't this work without that part of the statement?
Jay
No. The OVER clause in conjuction with PARTITION BY splits the result set into several partitions and then applies the aggregate function to this partitions. For further information, please read http://msdn.microsoft.com/en-us/library/ms189461.aspx.
Maximilian Mayerl
You need a `SUM(SUM(d))` here.
Quassnoi
Huh, SumSum(d))? Why? Is this Oracle specific or something like this? SQL Server reports an error when I try this...?
Maximilian Mayerl
Ah, fergot it, sorry, of course I need Sum(Sum(d)), because I'm already grouping. Forgot that part on my test query. I'll edit my answer.
Maximilian Mayerl
The innermost `SUM` is the aggregate (calculated before the `GROUP BY`), the outermost is analytic (calculated after the `GROUP BY`). `SQL Server` requires `SUM(SUM(d)) OVER (PARTITION BY a, b)` just as well.
Quassnoi
+1  A: 

Hi Tom,

you can do it with aliases:

SELECT a AS a1, b AS b1, c AS c1,
       (SELECT SUM(d)
           FROM test_t t_in
          WHERE t_in.a = t.a
            AND t_in.b = t.b) AS total
  FROM test_t t
 GROUP BY a, b, c
Vincent Malgrat