Skip to main content

Period Matirx Twisting

·1657 words·8 mins
Darren Pruitt
Author
Darren Pruitt

The Period Matrix table, Pd_Matrix, is used in calculating accounting period formulas. These formulas include current month, quarter or years activity or balance. These formulas can also be created using standard SQL functions but not all functions are common between SQL Server and MS Access. The Period Matrix has the advantage in that it can be used in any DBMS and it also can be used in table pivoting and folding.

The table listed below is for use with the Activity table and not the Balance table. Either a separate matrix table will have to be created or an additional field would have to be added for calculating account formulas with the Balance table.

Pd_TypePd_IDPd_Namepd_1pd_2pd_3pd_4pd_5pd_6pd_7pd_8pd_9pd_10pd_11pd_12
annual1YR111111111111
month1JAN100000000000
month2FEB010000000000
month3MAR001000000000
month4APR000100000000
month5MAY000010000000
month6JUN000001000000
month7JUL000000100000
month8AUG000000010000
month9SEP000000001000
month10OCT000000000100
month11NOV000000000010
month12DEC000000000001
quarter1QTR1111000000000
quarter2QTR2000111000000
quarter3QTR3000000111000
quarter4QTR4000000000111
semiannual1SA1111111000000
semiannual2SA2000000111111

Pd_Type
#

The Period Type is used to indicate the type of formula being used. The types listed are:

  • Month: The given months activity
  • Quarter: The given quarters activity
  • Semiannual: The given half-year activity
  • Annual: The entire years activity
  • Other types that could be created include a months or quarter ending balance.

Pd_ID and PD_Name
#

The Period ID and Name are used to identify a given time frame:

  • Month: The month number (1 thru 12) and name (January thru December)
  • Quarter: The quarter number (1 thru 4) and name (QTR1 thru QTR4)
  • Semiannual: The semiannual number (1 or2) and name (SA1 and SA2)
  • Annual: The year number (1) or name (YR)

pd_1 thru pd_12
#

The values for period 1 through 12 can only be 1 or 0. These fields are multiplied with the Activity table month fields to create the necessary formulas.

Creating Formulas
#

To create a formula using the Period Matrix and the Activity table you would create a select statement where in the period fields in the Activity table were multiplied to the period fields in the Matrix table then add them all together:

( Activity.Jan * Pd_Matrix.pd_1 + Activity.Feb * Pd_Matrix.pd_2  
Activity.Mar * Pd_Matrix.pd_3 + Activity.Apr * Pd_Matrix.pd_4  
Activity.May * Pd_Matrix.pd_5 + Activity.Jun * Pd_Matrix.pd_6  
Activity.Jul * Pd_Matrix.pd_7 + Activity.Aug * Pd_Matrix.pd_8  
Activity.Sep * Pd_Matrix.pd_9 + Activity.Oct * Pd_Matrix.pd_10  
Activity.Nov * Pd_Matrix.pd_11 + Activity.Dec * Pd_Matrix.pd_12)

In the WHERE clause of the select statement you would set the Period Type (Pd_Type) and Period Name (Pd_Name) of the Matrix table to the name of the formula. For example, if you wanted to show the monthly activity for January you would create the following select statement:

SELECT  
      Activity.AcctID  
     , Activity.DeptID  
     , Activity.Class  
     , Pd_Matrix.Pd_Name  
     , Activity.Year  
     , ( Activity.Jan * Pd_Matrix.pd_1 + Activity.Feb * Pd_Matrix.pd_2  
         + Activity.Mar * Pd_Matrix.pd_3 + Activity.Apr * Pd_Matrix.pd_4  
         + Activity.May * Pd_Matrix.pd_5 + Activity.Jun * Pd_Matrix.pd_6  
         + Activity.Jul * Pd_Matrix.pd_7 + Activity.Aug * Pd_Matrix.pd_8  
         + Activity.Sep * Pd_Matrix.pd_9 + Activity.Oct * Pd_Matrix.pd_10  
         + Activity.Nov * Pd_Matrix.pd_11 + Activity.Dec * Pd_Matrix.pd_12  
         ) As Amount  
  
FROM Activity, Pd_Matrix  
  
WHERE  
         (Pd_Type = 'month')  
     And (Pd_Matrix.Pd_Name = 'JAN')

This SQL statement could be changed to a parameterized stored procedure with variables for Pd_Type and Pd_Name. This would allow you to return a recordset for any of the given formulas.

Table Folding
#

The Period Matrix can also be
used in table folding, where the columns of the original table are converted to rows. This is accomplished by creating a Cartesian product between the original table, in our case the Activity table, and the Period Matrix table.

A Cartesian product result set, also known as a Cross Join, is familiar to people that have created SQL statements with bad or missing joins between tables. They are recognizable because the result set will have the same row multiple times or the total row count far exceeds the total number of expected rows. In most cases this is unwanted but it comes in very handy for table folding.

The following SQL select statement will fold the Activity table’s period activity columns into rows:

SELECT

       Activity.AcctID  
     , Activity.DeptID  
     , Activity.Class  
     , Pd_Matrix.Pd_Name  
     , Activity.Year  
     ,    (Activity.Jan * Pd_Matrix.pd_1 + Activity.Feb * Pd_Matrix.pd_2  
         + Activity.Mar * Pd_Matrix.pd_3 + Activity.Apr * Pd_Matrix.pd_4  
         + Activity.May * Pd_Matrix.pd_5 + Activity.Jun * Pd_Matrix.pd_6  
         + Activity.Jul * Pd_Matrix.pd_7 + Activity.Aug * Pd_Matrix.pd_8  
         + Activity.Sep * Pd_Matrix.pd_9 + Activity.Oct * Pd_Matrix.pd_10  
         + Activity.Nov * Pd_Matrix.pd_11 + Activity.Dec * Pd_Matrix.pd_12  
         ) As Amount  
  
FROM Activity, Pd_Matrix  
   
WHERE Pd_Type = 'month'

Note that this is identical to the SQL used to show the activity for just one month used previously, with the only exception being in the WHERE clause. Instead of indicating which month (Pd_Name) to show, the SQL was allowed to return all the available months.

This statement works for the same reasons the previous SQL statement worked. When the Pd_Name is JAN then pd_1 equals one while the rest of the pd_2 through pd_12 equals zero. When the multiplications are carried out all the results are all zero except for January’s, which is equal to the January activity. When the addition is carried out therefore only the January amount is returned.

Also, since there is no join between the two tables the result set will have twelve times the number of rows that the Activity table actually has. For each row in the Activity table there will be twelve rows generated in the result because there are twelve possible rows for the Pd_Type of ‘month’. If instead of choosing ‘month’ we had chosen ‘quarter’ for the Period Type then the results set would have four times the number of rows in the Activity table.

This method of table folding is fast and very simple to create and maintain. The most common way table folding is done though is by manually creating the final table then creating an append or update query for each column to fold. In the case of our example we would have had to create and execute thirteen queries in order to obtain the same results.

Table Folding and Pivoting Using Formulas
#

Where as table folding is deals with turning columns into rows, table pivoting is turning rows into columns.

Taking the example from the table folding section lets add the requirement that our resultset show the Actual and Budget amounts in separate columns. The periods will still be shown as rows.

The SQL needed in Access would be:

SELECT  

       Activity.AcctID  
     , Activity.DeptID  
     , Pd_Matrix.Pd_Name  
     , Activity.Year  
     ,Sum( IIF(Activity.Class = "Actual",  
         (Activity.Jan * Pd_Matrix.pd_1 + Activity.Feb * Pd_Matrix.pd_2  
         + Activity.Mar * Pd_Matrix.pd_3 + Activity.Apr * Pd_Matrix.pd_4  
         + Activity.May * Pd_Matrix.pd_5 + Activity.Jun * Pd_Matrix.pd_6  
         + Activity.Jul * Pd_Matrix.pd_7 + Activity.Aug * Pd_Matrix.pd_8  
         + Activity.Sep * Pd_Matrix.pd_9 + Activity.Oct * Pd_Matrix.pd_10  
         + Activity.Nov * Pd_Matrix.pd_11 + Activity.Dec * Pd_Matrix.pd_12  
         ), 0)) As Actual  
  
     ,Sum( IIF(Activity.Class = "Budget",  
         (Activity.Jan * Pd_Matrix.pd_1 + Activity.Feb * Pd_Matrix.pd_2  
         + Activity.Mar * Pd_Matrix.pd_3 + Activity.Apr * Pd_Matrix.pd_4  
         + Activity.May * Pd_Matrix.pd_5 + Activity.Jun * Pd_Matrix.pd_6  
         + Activity.Jul * Pd_Matrix.pd_7 + Activity.Aug * Pd_Matrix.pd_8  
         + Activity.Sep * Pd_Matrix.pd_9 + Activity.Oct * Pd_Matrix.pd_10  
         + Activity.Nov * Pd_Matrix.pd_11 + Activity.Dec * Pd_Matrix.pd_12  
         ), 0)) As Budget  
  
FROM Activity, Pd_Matrix  
  
WHERE Pd_Type = 'month'  
  
GROUP BY  
       Activity.AcctID  
     , Activity.DeptID  
     , Pd_Matrix.Pd_Name  
     , Activity.Year

In SQL Server the CASE statement would replace the IIF( ) function:

SELECT  

       Activity.AcctID  
     , Activity.DeptID  
     , Pd_Matrix.Pd_Name  
     , Activity.Year  
      
     ,Sum( CASE Activity.Class  
         WHEN "Actual"THEN  
         (Activity.Jan * Pd_Matrix.pd_1 + Activity.Feb * Pd_Matrix.pd_2  
         + Activity.Mar * Pd_Matrix.pd_3 + Activity.Apr * Pd_Matrix.pd_4  
         + Activity.May * Pd_Matrix.pd_5 + Activity.Jun * Pd_Matrix.pd_6  
         + Activity.Jul * Pd_Matrix.pd_7 + Activity.Aug * Pd_Matrix.pd_8  
         + Activity.Sep * Pd_Matrix.pd_9 + Activity.Oct * Pd_Matrix.pd_10  
         + Activity.Nov * Pd_Matrix.pd_11 + Activity.Dec * Pd_Matrix.pd_12  
         ) ELSE 0 END) Actual  
  
     ,Sum( CASE Activity.Class  
         WHEN "Budget"THEN  
         (Activity.Jan * Pd_Matrix.pd_1 + Activity.Feb * Pd_Matrix.pd_2  
         + Activity.Mar * Pd_Matrix.pd_3 + Activity.Apr * Pd_Matrix.pd_4  
         + Activity.May * Pd_Matrix.pd_5 + Activity.Jun * Pd_Matrix.pd_6  
         + Activity.Jul * Pd_Matrix.pd_7 + Activity.Aug * Pd_Matrix.pd_8  
         + Activity.Sep * Pd_Matrix.pd_9 + Activity.Oct * Pd_Matrix.pd_10  
         + Activity.Nov * Pd_Matrix.pd_11 + Activity.Dec * Pd_Matrix.pd_12  
         ) ELSE 0 END) Budget  
  
FROM Activity, Pd_Matrix  
  
WHERE Pd_Type = 'month'  
   
GROUP BY  
     Activity.AcctID  
     , Activity.DeptID  
   
     , Pd_Matrix.Pd_Name  
     , Activity.Year  

Summary
#

The Period Matrix table is a versatile tool for SQL development. It can be used in all DBMSs with little modification to the SQL statements. It can be used to replace several separate SQL statements needed to create the different formulas and it is useful in table folding and pivoting.