dbTalk Databases Forums  

Calculating SUM and COUNT in one statement

comp.databases comp.databases


Discuss Calculating SUM and COUNT in one statement in the comp.databases forum.



Reply
 
Thread Tools Display Modes
  #11  
Old   
Tony
 
Posts: n/a

Default Re: Calculating SUM and COUNT in one statement - 02-24-2004 , 04:46 AM






"Bob Badour" <bbadour (AT) golden (DOT) net> wrote

Quote:
"Tony" <andrewst (AT) onetel (DOT) net.uk> wrote in message
news:c0e3f26e.0402230443.605ca7e9 (AT) posting (DOT) google.com...
christian.maslen (AT) techie (DOT) com (Christian Maslen) wrote in message
news:<b9c8cfba.0402230001.5fb27d77 (AT) posting (DOT) google.com>...
how could such a query look like (and don't tell me about UNION ALL)?

You haven't mentioned which database. So I'm assuming it's ANSI-92
compliant.

SELECT S1.COL1
,S2.SUM_AMT
, COUNT(*)
FROM SOME_TABLE as S1
,(SELECT SUM(COL1) as SUM_AMT
FROM SOME_TABLE) as S1
GROUP BY S1.COL1
,S2.SUM_AMT;

As Lee pointed out it won't happen in a single scan.

Christian.

A single scan is possible in Oracle, using a non-ANSI extension to SQL:

SQL> select deptno, count(*), sum(count(*)) over ()
2 from emp
3 group by deptno;

If he were summing counts and not col1's, that might actually work.
OK, a more directly equivalent example:

SQL> select sal, count(*), (sum(sal) over ())
2 from emp
3 group by sal;

SAL COUNT(*) (SUM(SAL)OVER())
---------- ---------- ----------------
800 1 24775
950 1 24775
1100 1 24775
1250 2 24775
1300 1 24775
1500 1 24775
1600 1 24775
2450 1 24775
2850 1 24775
2975 1 24775
3000 2 24775
5000 1 24775

12 rows selected.


Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=54 Card=12 Bytes=36)
1 0 WINDOW (BUFFER)
2 1 SORT (GROUP BY) (Cost=54 Card=12 Bytes=36)
3 2 TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=14 Bytes=42)




Statistics
----------------------------------------------------------
0 recursive calls
4 db block gets
1 consistent gets
0 physical reads
0 redo size
674 bytes sent via SQL*Net to client
496 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
4 sorts (memory)
0 sorts (disk)
12 rows processed


Reply With Quote
  #12  
Old   
Tony
 
Posts: n/a

Default Re: Calculating SUM and COUNT in one statement - 02-24-2004 , 05:47 AM






"Bob Badour" <bbadour (AT) golden (DOT) net> wrote

Quote:
"Tony" <andrewst (AT) onetel (DOT) net.uk> wrote in message
news:c0e3f26e.0402230443.605ca7e9 (AT) posting (DOT) google.com...
christian.maslen (AT) techie (DOT) com (Christian Maslen) wrote in message
news:<b9c8cfba.0402230001.5fb27d77 (AT) posting (DOT) google.com>...
how could such a query look like (and don't tell me about UNION ALL)?

You haven't mentioned which database. So I'm assuming it's ANSI-92
compliant.

SELECT S1.COL1
,S2.SUM_AMT
, COUNT(*)
FROM SOME_TABLE as S1
,(SELECT SUM(COL1) as SUM_AMT
FROM SOME_TABLE) as S1
GROUP BY S1.COL1
,S2.SUM_AMT;

As Lee pointed out it won't happen in a single scan.

Christian.

A single scan is possible in Oracle, using a non-ANSI extension to SQL:

SQL> select deptno, count(*), sum(count(*)) over ()
2 from emp
3 group by deptno;

If he were summing counts and not col1's, that might actually work.
Damn! Wish I knew how to "recall" a post! I just responded to this
with another wrong solution, but now I think I have the correct
solution. However, before this one appears you will see my 2nd wrong
solution and respond to that...

My mistake was treating the sum(sal) as if it operated on the base
table rather than on the result set after grouping. I believe this
finally fixes it and still only requires one scan of the table:

SQL> select sal, cnt, sum(sal*cnt) over () totsal
2 from
3 (
4 select sal, count(*) cnt
5 from emp
6 group by sal
7 );

SAL CNT TOTSAL
---------- ---------- ----------
800 1 29025
950 1 29025
1100 1 29025
1250 2 29025
1300 1 29025
1500 1 29025
1600 1 29025
2450 1 29025
2850 1 29025
2975 1 29025
3000 2 29025
5000 1 29025

12 rows selected.


Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=54 Card=12 Bytes=312
)

1 0 WINDOW (BUFFER)
2 1 VIEW (Cost=54 Card=12 Bytes=312)
3 2 SORT (GROUP BY) (Cost=54 Card=12 Bytes=36)
4 3 TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=14 Bytes=4
2)





Statistics
----------------------------------------------------------
0 recursive calls
4 db block gets
1 consistent gets
1 physical reads
0 redo size
629 bytes sent via SQL*Net to client
534 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
3 sorts (memory)
0 sorts (disk)
12 rows processed


Reply With Quote
  #13  
Old   
Bob Badour
 
Posts: n/a

Default Re: Calculating SUM and COUNT in one statement - 02-24-2004 , 08:51 AM



"Tony" <andrewst (AT) onetel (DOT) net.uk> wrote

Quote:
"Bob Badour" <bbadour (AT) golden (DOT) net> wrote

"Tony" <andrewst (AT) onetel (DOT) net.uk> wrote in message
news:c0e3f26e.0402230443.605ca7e9 (AT) posting (DOT) google.com...
christian.maslen (AT) techie (DOT) com (Christian Maslen) wrote in message
news:<b9c8cfba.0402230001.5fb27d77 (AT) posting (DOT) google.com>...
how could such a query look like (and don't tell me about UNION
ALL)?

You haven't mentioned which database. So I'm assuming it's ANSI-92
compliant.

SELECT S1.COL1
,S2.SUM_AMT
, COUNT(*)
FROM SOME_TABLE as S1
,(SELECT SUM(COL1) as SUM_AMT
FROM SOME_TABLE) as S1
GROUP BY S1.COL1
,S2.SUM_AMT;

As Lee pointed out it won't happen in a single scan.

Christian.

A single scan is possible in Oracle, using a non-ANSI extension to
SQL:

SQL> select deptno, count(*), sum(count(*)) over ()
2 from emp
3 group by deptno;

If he were summing counts and not col1's, that might actually work.

Damn! Wish I knew how to "recall" a post! I just responded to this
with another wrong solution, but now I think I have the correct
solution. However, before this one appears you will see my 2nd wrong
solution and respond to that...
You were fortunate that I showed some uncharacteristic restraint.


Quote:
My mistake was treating the sum(sal) as if it operated on the base
table rather than on the result set after grouping. I believe this
finally fixes it and still only requires one scan of the table:

SQL> select sal, cnt, sum(sal*cnt) over () totsal
2 from
3 (
4 select sal, count(*) cnt
5 from emp
6 group by sal
7 );

SAL CNT TOTSAL
---------- ---------- ----------
800 1 29025
950 1 29025
1100 1 29025
1250 2 29025
1300 1 29025
1500 1 29025
1600 1 29025
2450 1 29025
2850 1 29025
2975 1 29025
3000 2 29025
5000 1 29025

12 rows selected.
Thanks for clarifying that.




Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.