views:

65

answers:

2

I'm trying to get a report built up from data mining our accounting software.

We have a table that stores the balances of each account in a general ledger for a given period (which is 0-12, 0 being carry over from last year, 1-12 being the corresponding month), the amount, and other data I don't need.

I'm trying unsuccessfully to get a value for each account for each month, however there isn't always a corresponding entry. I've tried left outer joins, cross joins, inner joins, and can't seem to get it to work how I want. I've even tried doing left outer joins with a table containing 'Initial' as item 0 and 12 other entries, one name for each month.

Here's a sample of the data:

GLBalances table:

acct_no  |  post_prd  | post_trn_amt
  1011   |     0      |  -15000
  1011   |     1      |  5000
  1011   |     2      |  -6000
  1011   |     4      |  8000
  1020   |     5      |  100
  1020   |     12     |  300
  1011   |     9      |  500
  1011   |     8      |    0
etc...

What I'd like to get out is:

 acct_no | post_prd   | post_trn_amt
  1011   |     0      |  -15000
  1011   |     1      |  5000
  1011   |     2      |  -6000
  1011   |     3      |     0
  1011   |     4      |  8000
  1011   |     5      |     0
  1011   |     6      |     0
  1011   |     7      |     0
  1011   |     8      |     0
  1011   |     9      |   500
  1011   |     10     |     0
  1011   |     11     |     0
  1011   |     12     |     0
  1020   |     0      |     0
  1020   |     1      |     0
  1020   |     2      |     0
  1020   |     3      |     0
  1020   |     4      |     0
  1020   |     5      |     100
  1020   |     6      |     0
  1020   |     7      |     0
  1020   |     8      |     0
  1020   |     9      |     0
  1020   |    10      |     0
  1020   |    11      |     0
  1020   |    12      |     300

etc...

So basically 13 entries for each acct for a particular year even if there's no entry for that period.

I'm sure this is way easier than I'm making it, I'm just struggling since I don't deal with SQL on a daily basis. Any help would be much appreciated.

A: 

I think this article will be helpful:

http://msdn.microsoft.com/en-us/library/aa175780%28SQL.80%29.aspx

Added

This is very similar to a commonly asked question - "how do I get all dates in a date range". I realise you're using integer months, and not actual dates, but the concept is similar.

Here's a solution for the date question that you could probably modify for you situation.

http://stackoverflow.com/questions/271595/getting-dates-between-a-range-of-dates

David Stratton
+3  A: 

You can create a sheet of valid accounts and months with cross join. Look for the corresponding "real" row with a left join, and you're set:

;with months as
(
    select 0 as Month
    union all
    select Month + 1 from months where Month < 12
)
select a.acct_no, m.month as post_prd, IsNull(g.post_trn_amt,0)
from months m
cross join (select  distinct acct_no from @GLBalances) a
left join @GLBalances g 
    on m.month = g.post_prd 
    and a.acct_no = g.acct_no
order by a.acct_no, m.month

The "with months as" construct is a fancy way to create a table containing numbers 0 to 12. You can also create a real table containing those numbers, and do away with the "recursive common table expression" construct.

Here's the test data I used:

declare @GLBalances table (acct_no int, post_prd int, post_trn_amt int)
insert into @GLBalances
select 1011,0,-15000
union all select 1011, 1, 5000
union all select 1011, 2, -6000
union all select 1011, 4, 8000
union all select 1020, 5, 100
union all select 1020, 12, 300
union all select 1011, 9, 500
union all select 1011, 8, 0
Andomar
+1. Good concise answer with workable code. Pretty much the same code as in my second link, but already modified for @Josh's needs. Again, good answer.
David Stratton