|
database
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Problem Using AliasI also need to "roll up" the sums into a "higher level" sum based on some other tables. This is an accounting database, where subaccounts roll up into a single account (i.e. subaccounts 101 and 102 roll up into account 100). I'm using an alias, but not getting correct results. I believe I'm ending up with a cartesian product, but not sure of the "fix". Note: I cannot change the table design, this is an existing accounting database created by a different application. Here's a simplified version of the query with tables following that: SELECT Account.Name, Sum(A.Amount) as Actual, Sum(B.Amount) as Budget FROM Account, SubAccount, Trans A, Trans B WHERE Account.AccountNum = SubAccount.AccountNum and Trans.SubAccountNum = SubAccount.SubAccountNum and A.Trans.Type = 'A' and B.Trans.Type = 'B' GROUP BY Account.Name What's wrong with my SQL above? Here are my tables with sample data: Table: Account AccountNum Name -------------------- 100 Fuel 200 Tires Table: SubAccount AccountNum SubAccountNum Name -------------------------------------------- 100 101 Diesel 100 102 Gasoline 200 200 Winter Tire 200 201 All Season Tire Table: Trans (transactions) SubAccountNum Amount Type (A-Actual, B-Budget) ------------------------------------------------- 101 10 A 102 20 A 200 30 A 201 40 A 101 50 B 102 60 B 200 70 B 201 80 B >From the data above, I need to end up with output from my Select as Name Actual Budgetfollows: ---------------------- Fuel 30 110 Tires 70 150 > FROM Account, SubAccount, Trans A, Trans B Please use ANSI inner joins. It will make your query easier to read and will allow you to > Trans.SubAccountNum = SubAccount.SubAccountNum and You're saying, instead of calling Trans "Trans", let's call it "A". What do > A.Trans.Type = 'A' and B.Trans.Type = 'B' you expect A.Trans to mean? Didn't you mean A.SubAccountNum = SubAccount.SubAccountNum AND A.Type = 'A' AND B.Type = 'B' I have a better way to formulate the query however, because of my first point, I have no idea whether two copies of the Trans table are required, how they each relate to Account and SubAccount, and how the sums should be generated. If you provide more details I'd be more than happy to write you a more readable query. Please see: http://www.aspfaq.com/5006 As you said, I should be using joins. The code below did the trick.
Thanks for your input. SELECT Account.Name, Sum(Case Trans.Type When 'A' Then Trans.Amount Else 0 End) as Actual, Sum(Case Trans.Type When 'B' Then Trans.Amount Else 0 End) as Budget FROM Account INNER JOIN SubAccount ON Account.AccountNum = SubAccount.AccountNum INNER JOIN Trans ON Trans.SubAccountNum = SubAccount.SubAccountNum > Please use ANSI inner joins. It will make your query easier to read and finish sentences! What I was going to elaborate on about is that you can > will allow you to separate join and filter criteria. Looks like you've already got a handle on it in this case. CREATE TABLE Accounts (AccountNum int NOT NULL, [name] varchar(25), PRIMARY
KEY (AccountNum)) GO CREATE TABLE SubAccounts (AccountNum int REFERENCES Accounts(AccountNum), SubAccountNum int, [name] varchar(25)) GO INSERT INTO Accounts VALUES (100, 'Fuel') INSERT INTO Accounts VALUES (200, 'Tires') INSERT INTO SubAccounts VALUES (100,101,'Diesel') INSERT INTO SubAccounts VALUES (100,102,'Gasoline') INSERT INTO SubAccounts VALUES (200,200,'Winter Tire') INSERT INTO SubAccounts VALUES (200,201,'All Season Tire') CREATE TABLE Trans (SubAccountNum int, Amount int, Type char(1)) GO INSERT INTO test4 VALUES (101,10,'A') INSERT INTO test4 VALUES (102,20,'A') INSERT INTO test4 VALUES (200,30,'A') INSERT INTO test4 VALUES (201,40,'A') INSERT INTO test4 VALUES (101,50,'B') INSERT INTO test4 VALUES (102,60,'B') INSERT INTO test4 VALUES (200,70,'B') INSERT INTO test4 VALUES (201,80,'B') SELECT a.[name], SUM(t1.TotalActual) AS "Total Actual", SUM(t2.TotalBudgeted) AS "Total Budgeted" FROM Accounts a INNER JOIN SubAccounts sa ON a.AccountNum=sa.AccountNum INNER JOIN (SELECT SubAccountNum, SUM(Amount) AS "TotalActual" FROM Trans WHERE Type='A' GROUP BY SubAccountNum) t1 ON t1.SubAccountNum=sa.SubAccountNum INNER JOIN (SELECT SubAccountNum, SUM(Amount) AS "TotalBudgeted" FROM Trans WHERE Type='B' GROUP BY SubAccountNum) t2 ON t2.SubAccountNum=sa.SubAccountNum GROUP BY a.[name] Show quote "joeacu***@yahoo.com" wrote: > I need a select that sums the same column, but with different criteria. > I also need to "roll up" the sums into a "higher level" sum based on > some other tables. This is an accounting database, where subaccounts > roll up into a single account (i.e. subaccounts 101 and 102 roll up > into account 100). > > I'm using an alias, but not getting correct results. I believe I'm > ending up with a cartesian product, but not sure of the "fix". Note: I > cannot change the table design, this is an existing accounting database > created by a different application. > > Here's a simplified version of the query with tables following that: > > SELECT Account.Name, Sum(A.Amount) as Actual, Sum(B.Amount) as Budget > FROM Account, SubAccount, Trans A, Trans B > WHERE > Account.AccountNum = SubAccount.AccountNum and > Trans.SubAccountNum = SubAccount.SubAccountNum and > A.Trans.Type = 'A' and B.Trans.Type = 'B' > GROUP BY Account.Name > > What's wrong with my SQL above? > > Here are my tables with sample data: > > Table: Account > AccountNum Name > -------------------- > 100 Fuel > 200 Tires > > Table: SubAccount > AccountNum SubAccountNum Name > -------------------------------------------- > 100 101 Diesel > 100 102 Gasoline > 200 200 Winter Tire > 200 201 All Season Tire > > Table: Trans (transactions) > SubAccountNum Amount Type (A-Actual, B-Budget) > ------------------------------------------------- > 101 10 A > 102 20 A > 200 30 A > 201 40 A > 101 50 B > 102 60 B > 200 70 B > 201 80 B > > >From the data above, I need to end up with output from my Select as > follows: > > Name Actual Budget > ---------------------- > Fuel 30 110 > Tires 70 150 > > |
|||||||||||||||||||||||