Reputation: 2607
How do I retain the Acct_Name
field where appropriate when summing the data below by the Amount
column and grouping by the Line_Num
field? The "Null" values in Line_Num
column cause a problem in the grouping terms when the account name is added. Accounts C and D both have Null values in Line_Num
. If I add Acct_Name
to the group by
clause, I lose the ability to sum the values only by the Line_Num
field.
I am attempting to sum lines of accounting and group based on the line number. The null data isn't my doing, unfortunately it's just the data set I was handed.
Original data:
Acct_Name ID Line_Num Amount
Acct A 1 1_01 100.0000
Acct A 1 1_01 -50.0000
Acct A 1 1_02 75.0000
Acct A 1 _02 125.0000
Acct B 2 2_01 200.0000
Acct B 2 2_01 50.0000
Acct B 2 2_02 25.0000
Acct C 3 3_01 75.0000
Acct C 3 3_02 50.0000
Acct C 3 3_03 -25.0000
Acct C 3 Null 65.0000
Acct D 4 Null 300.0000
Acct D 4 _02 100.0000
Acct D 4 Null -50.0000
Acct D 4 Null 75.0000
If the Line_Num
value is null, that line is allowed to be aggregated with the other null values. It will show up in reports as being unaccounted for and it can be dealt with appropriately.
Ideal processed data set:
Amount Line_Num Acct_Name
390.00 Null Null
225.00 _02 Null
50.00 1_01 Acct A
75.00 1_02 Acct A
250.00 2_01 Acct B
25.00 2_02 Acct B
75.00 3_01 Acct C
50.00 3_02 Acct C
-25.00 3_03 Acct C
Here are the following queries I have used:
Select SUM(Amount), Line_Num
FROM dbo.tblRawData
Group By Line_Num
This query works just fine, but it does not include the account name in any of the aggregated fields. I need the account name in the fields that did not contain null values.
Select SUM(Amount), Line_Num, Acct_Name
FROM dbo.tblRawData
Group By Line_Num, Acct_Name
This query includes the account name, but it ends up grouping based on Account Name and not just Line_Num.
Select *
From dbo.tblRawData a
Inner Join dbo.tblRawData b On (a.Line_Num = b.Line_Num)
(SELECT SUM(CAST(Amount as money)) as Amount, Line_Num
FROM dbo.tblRawData
GROUP BY Line_Num)
This inner join is intended to join only those lines that are equivalent on the Line Num, but I am receiving a cartesian result set. Clearly I have not written this join correctly or I am using the incorrect command.
Here is the query that can be used to build the same schema that I am using:
CREATE TABLE [dbo].[tblRawData](
[Acct_Name] [nvarchar](50) NULL,
[ID] [nvarchar](50) NULL,
[Line_Num] [nvarchar] (50),
[Amount] [money]
) ON [PRIMARY]
GO
insert into dbo.tblRawData values ('Acct A', '1', '1_01', '100')
insert into dbo.tblRawData values ('Acct A', '1', '1_01', '-50')
insert into dbo.tblRawData values ('Acct A', '1', '1_02', '75')
insert into dbo.tblRawData values ('Acct A', '1', '_02', '125')
insert into dbo.tblRawData values ('Acct B', '2', '2_01', '200')
insert into dbo.tblRawData values ('Acct B', '2', '2_01', '50')
insert into dbo.tblRawData values ('Acct B', '2', '2_02', '25')
insert into dbo.tblRawData values ('Acct C', '3', '3_01', '75')
insert into dbo.tblRawData values ('Acct C', '3', '3_02', '50')
insert into dbo.tblRawData values ('Acct C', '3', '3_03', '-25')
insert into dbo.tblRawData values ('Acct C', '3', '', '65')
insert into dbo.tblRawData values ('Acct D', '4', '', '300')
insert into dbo.tblRawData values ('Acct D', '4', '_02', '100')
insert into dbo.tblRawData values ('Acct D', '4', '', '-50')
insert into dbo.tblRawData values ('Acct D', '4', '', '75')
P.S. SQL Fiddle appears to be inaccessible at the moment (might be on my end, don't know)
Edit
Take a look at the following code and holler if it seems that there are blatant flaws in trying to accomplish my goal. I'd prefer for Acct_Name
to remain null if Line_Item
doesn't match up, but perhaps I can sort that out.
IF (SELECT object_id('TempDB..#temp4')) IS NOT NULL
BEGIN
DROP TABLE #temp4
END
SELECT SUM(CAST(Amount as money)) as Amount, Line_Num INTO #temp4
FROM dbo.tblRawData
GROUP BY Line_Num
Select * from #temp4
Select MAX(a.Acct_Name) as Acct_Name, MAX(b.Line_Num) as Line_Num, MAX(b.Amount) as Amount
From dbo.tblRawData a
Inner Join #temp4 b On (a.Line_Num = b.Line_Num)
Group By b.Line_Num
Results:
Acct_Name Line_Num Amount
Acct D Null 390.00
Acct D _02 225.00
Acct A 1_01 50.00
Acct A 1_02 75.00
Acct B 2_01 250.00
Acct B 2_02 25.00
Acct C 3_01 75.00
Acct C 3_02 50.00
Acct C 3_03 -25.00
Upvotes: 2
Views: 105
Reputation: 70638
Here you go:
;WITH CTE AS
(
SELECT Line_Num,
SUM(Amount) Amount,
MIN(Acct_Name) MinAcct_Name,
MAX(Acct_Name) MaxAcct_Name
FROM tblRawData
GROUP BY Line_Num
)
SELECT Amount,
Line_Num,
CASE WHEN Line_Num IS NULL
OR MinAcct_Name <> MaxAcct_Name THEN NULL
ELSE MinAcct_Name END Acct_Name
FROM CTE
Upvotes: 2