Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Multiple Aggregate Columns in select statement

Author  Topic 

karuna
Aged Yak Warrior

582 Posts

Posted - 2005-10-13 : 07:13:36
I want to have a multiple aggregate columns in a select statement from a different tables how can I do this?

TableA
Product Quantity
abc 5
abc 10
abc 15
xyz 10

TableB
Product Units
abc 10
abc 5
def 10



my result should be


Product Quantity Unit Difference
abc 30 15 15
xyz 10 10
def 10 10


Nested joins will do the trick?

Thanks



Karunakaran

chiragkhabaria
Master Smack Fu Yak Hacker

1907 Posts

Posted - 2005-10-13 : 07:57:57
Check this whether its gives you the desired output..


Select d.Product ,isNull(a.quantity,0) Quantity ,isNull(b.unit,0) Unit,IsNull(a.quantity,0)- Isnull(b.unit,0) As 'Difference' From
(Select Distinct Product From tbl2 union Select Distinct products From tbl1) d
left outer join
(Select product,sum(Quantity) as Quantity from tbl1 Group by Product) a on
a.products = d.product
left outer join (Select product,sum(Unit) as Unit from tbl2 Group by Product) b on
b.product = d.product




Complicated things can be done by simple thinking
Go to Top of Page

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2005-10-13 : 07:59:47
Try this
Select Case when Product is null then Product1 else product end as Product,Sum(Distinct Quantity) as Quantity,
Sum(Distinct units) as Units ,Abs(Isnull(Sum(Distinct Quantity),0) - Isnull(Sum(Distinct units),0)) as Diff from
(
Select T1.*, T2.Product as product1, T2.units from TableA T1
Full outer join TableB T2 on T1.product=T2.product
) T
group by Product,Product1 order by Product


Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2005-10-13 : 08:42:59
No full outer joins, please!
(you know I hate those!)

It doesn't seem like the obvious answer, but a very simple and quick way to get the answer is with a UNION:


Select Product, Sum(Units) as Units, Sum(Quantity) as Qty, sum(Units) - sum(Quantity) as Diff
from
(
select Product, 0 as Units, Quantity
from TableA
union all
select Product, Units, 0 as Quantity
from TableB
) a
group by Product


It's a very powerful and quick trick to "rolling together" results from two different tables, especially if you can't join directly from one table to the next since some rows might only exist in one table or the other; for example, to compare a Budget table with an Actuals table.
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2005-10-13 : 08:45:55
chiragkhabaria --

By the way, in this statement:

Select Distinct Product From tbl2 union Select Distinct products From tbl1

the DISTINCTs are redundant since the UNION operator ensures on distinct values are returned by the SELECT. Always remember the difference between UNION and UNION ALL, since many times you might really want UNION ALL and it is much more efficient than UNION.
Go to Top of Page

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2005-10-13 : 08:46:18
>>It doesn't seem like the obvious answer, but a very simple and quick way to get the answer is with a UNION:

No doubt. You always have good Solution

Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

chiragkhabaria
Master Smack Fu Yak Hacker

1907 Posts

Posted - 2005-10-13 : 08:50:48
Aha.. thanks.. will keep in mind next time.. :-)..

by the way can you let me know what is wrong with the Full outer join .. ???

Complicated things can be done by simple thinking
Go to Top of Page

karuna
Aged Yak Warrior

582 Posts

Posted - 2005-10-13 : 09:29:18
Thanks for all...For the suggestions...
Meanwhile I got my solution. Might not be an optimal way...I'll try all these solutions.
I'll also post entire ddl, dml after sometime for review of the query.
I'm sure somebody will comeup with a better solution.

Karunakaran
Go to Top of Page

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2005-10-13 : 09:41:10
>>Meanwhile I got my solution. Might not be an optimal way...

I think jeff's is more optimal
Can you post your solution?

Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2005-10-13 : 09:52:56
quote:
Originally posted by chiragkhabaria

Aha.. thanks.. will keep in mind next time.. :-)..

by the way can you let me know what is wrong with the Full outer join .. ???

Complicated things can be done by simple thinking



Now, this is stricly my humble opinion, but I feel that FULL and RIGHT outer joins should never be used.

RIGHT -- your SELECT is poorly structured; you've chosen the wrong "source" in your FROM clause, it should be rewritten more clearly and in a more structured manner. Alll RIGHT joins can be rewritten using LEFT joins, and the result is (99.9999% of time -- haven't seen the exception yet) more clear and intuitive than with RIGHT joins.

FULL -- A FULL JOIN results in an unclear SELECT w/o a true primary source -- again, you have a fundamental problem with your SELECT statement's FROM clause. You should chose a new "starting" point covering all possibilities (often with a UNION) and use LEFT joins, or simply use a UNION as demonstrated in this thread. Also, a CROSS JOIN will sometimes generate that "all possibilities" primary source and from there you can LEFT JOIN to tables as needed. In addition, EVERY column of EVERY table involved in a FULL OUTER JOIN can come back NULL, so EVERY column in EVERY table needs to be surrounded by ISNULL() or COALESCE(). Any further joining or processing or use of a FULL OUTER JOIN immediately negates any use of indexes due to this.

Take it for what it is worth; I am not a great DBA, I am not the best data modeller out there, I definitely am not good with security or replication, but when it comes to writing short and efficient SELECT's that I feel pretty confident that I can offer great advice.
Go to Top of Page

karuna
Aged Yak Warrior

582 Posts

Posted - 2005-10-13 : 10:05:58
quote:
Originally posted by madhivanan

>>Meanwhile I got my solution. Might not be an optimal way...

I think jeff's is more optimal
Can you post your solution?

Madhivanan

Failing to plan is Planning to fail



Indeed... Jeff's very quicker than what I have written. Simple and Neat Solutions. Thanks Jeff.

Karunakaran
Go to Top of Page

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2005-10-13 : 10:08:27
Good Explanation Jeff

Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

karuna
Aged Yak Warrior

582 Posts

Posted - 2005-10-13 : 10:12:07
quote:
Originally posted by jsmith8858

No full outer joins, please!
(you know I hate those!)

It doesn't seem like the obvious answer, but a very simple and quick way to get the answer is with a UNION:


Select Product, Sum(Units) as Units, Sum(Quantity) as Qty, sum(Units) - sum(Quantity) as Diff
from
(
select Product, 0 as Units, Quantity
from TableA
union all
select Product, Units, 0 as Quantity
from TableB
) a
group by Product




Select Product, Sum(Units) as Units, Sum(Quantity) as Qty, sum(Units) - sum(Quantity) as Diff
from
(
select Product, 0 as Units, Quantity
from TableA
union all
select Product, Units, 0 as Quantity
from TableB
) a
where sum(Units) - sum(Quantity) != 0 - This gives me error
group by Product
[/code]

Karunakaran
Go to Top of Page

chiragkhabaria
Master Smack Fu Yak Hacker

1907 Posts

Posted - 2005-10-13 : 10:16:24
Select Product, Sum(Units) as Units, Sum(Quantity) as Qty, sum(Units) - sum(Quantity) as Diff
from
(
select Product, 0 as Units, Quantity
from TableA
union all
select Product, Units, 0 as Quantity
from TableB
) a
group by Product
Having
sum(Units) - sum(Quantity) != 0

hope this helps you....




Complicated things can be done by simple thinking
Go to Top of Page

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2005-10-13 : 10:18:07
That should be

Select Product, Sum(Units) as Units, Sum(Quantity) as Qty, sum(Units) - sum(Quantity) as Diff
from
(
select Product, 0 as Units, Quantity
from TableA
union all
select Product, Units, 0 as Quantity
from TableB
) a
group by Product
Having sum(Units) - sum(Quantity) != 0

Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

chiragkhabaria
Master Smack Fu Yak Hacker

1907 Posts

Posted - 2005-10-13 : 10:18:58
oh 2 mins.. :-)

Complicated things can be done by simple thinking
Go to Top of Page

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2005-10-13 : 10:19:31


Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

karuna
Aged Yak Warrior

582 Posts

Posted - 2005-10-13 : 11:34:17
Thanks...



Karunakaran
Go to Top of Page

karuna
Aged Yak Warrior

582 Posts

Posted - 2005-10-13 : 16:53:55
quote:
Originally posted by madhivanan

>>Meanwhile I got my solution. Might not be an optimal way...

I think jeff's is more optimal
Can you post your solution?

Madhivanan

Failing to plan is Planning to fail



This is what I wrote to get the result. Jeff's Solution is pretty cool.

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[TestTblKK]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[TestTblKK]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[TestTblKK1]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[TestTblKK1]
GO

CREATE TABLE [dbo].[TestTblKK] (
[Products] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[Quantity] [int] NOT NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[TestTblKK1] (
[Products] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[Units] [int] NOT NULL
) ON [PRIMARY]
GO

INSERT INTO TestTblKK VALUES('ABC',5)
INSERT INTO TestTblKK VALUES('ABC',10)
INSERT INTO TestTblKK VALUES('ABC',15)
INSERT INTO TestTblKK VALUES('XYZ',10)
INSERT INTO TestTblKK1 VALUES('ABC',5)
INSERT INTO TestTblKK1 VALUES('ABC',10)
INSERT INTO TestTblKK1 VALUES('DEF',10)



SELECT PROD,QUANTITY,UNITS, ISNULL(QUANTITY,0)-ISNULL(UNITS,0) AS VARIANCE FROM
(
SELECT PRODUCTS AS PROD ,SUM(QUANTITY) AS QUANTITY,UNITS FROM TestTblKK
LEFT JOIN
(Select PRODUCTS AS PROD,SUM(UNITS) AS UNITS FROM TestTblKK1 GROUP BY PRODUCTS --WHERE
) T
ON PRODUCTS= PROD --WHERE
GROUP BY PRODUCTS,UNITS) T2 WHERE ISNULL(UNITS,0)-ISNULL(QUANTITY,0) !=0
GROUP BY PROD, QUANTITY, UNITS
UNION

SELECT PROD,QUANTITY,UNITS, ISNULL(QUANTITY,0)-ISNULL(UNITS,0) AS VARIANCE FROM
(
SELECT PRODUCTS AS PROD ,SUM(UNITS) AS UNITS,QUANTITY FROM TestTblKK1
LEFT JOIN
(Select PRODUCTS AS PROD,SUM(QUANTITY) AS QUANTITY FROM TestTblKK
GROUP BY PRODUCTS) T
ON PROD = PRODUCTS GROUP BY PRODUCTS,QUANTITY) T2 WHERE ISNULL(UNITS,0)-ISNULL(QUANTITY,0) != 0
GROUP BY PROD, UNITS, QUANTITY


Thanks

Karunakaran
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2005-10-13 : 18:27:48
My motto is always: simple = good !

Glad I could help give you an easier solution that also makes sense.
Go to Top of Page

karuna
Aged Yak Warrior

582 Posts

Posted - 2005-10-14 : 00:32:24
quote:
Originally posted by jsmith8858

My motto is always: simple = good !

Glad I could help give you an easier solution that also makes sense.



It never striked me that this can be achieved with Union...
Well, thats why I'm asking question and you are answering !!!
For the analysis of others, I'll see if I could post the Execution Plan for both the versions, while your query has less table scan , mine had nested loops inside nested loops and so on....

Where all you can have unions in place of joins?

Thanks for all your help.

Karunakaran
Go to Top of Page
    Next Page

- Advertisement -