Saturday 16 April 2011

Compare values of two rows

Case
I get the cumulative sales each week, but I want to know the sales per week.

This is what I have:
WeekNrBikeSales
1Red bike4
1Green bike2
1Black bike5
1Blue bike1
2Red bike6
2Green bike7
2Black bike7
2Blue bike4
3Red bike7
3Green bike8
3Black bike9
3Blue bike6

And this is what I want:

WeekNrBikeCumuSalesWeekSales
1Black bike55
2Black bike72
3Black bike92
1Blue bike11
2Blue bike43
3Blue bike62
1Green bike22
2Green bike75
3Green bike81
1Red bike44
2Red bike62
3Red bike71

Solution
One of the solutions is to sort the rows on the key column (Bike in this case) and then on the week number. Then you can compare each row to the previous row to calculate the week sales.

1) Source and Sorting
This example uses a CSV source, so I have to add a Sort Transformation. If your source is a database you can add an ORDER BY clause in the source query. Sort the rows on Bike (1) and WeekNr (2).
The WeekNr and Sales are integers and the Bike is a varchar/string column.
Sorting is important for this solution.


















2) Script Component
Add a Script Component (type transformation) and add all rows as readonly input columns.
ReadOnly Input Columns



















3) Add new output column
On the Inputs and Outputs tab, add a new integer (DT_I4) column named WeekSales to store the sales per week.
Add new output column



















4) The Script
Go to the Script tab and add the following C# code:
// C# Code
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
    // Variables to store the previous row
    string Bike = "";
    int WeekNr = 0;
    int Sales = 0;

    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        // Compare current key with previous key
        if (Row.Bike == Bike)
        {
            // Keys match, so you can compare current sales with previous sales
            Row.WeekSales = Row.Sales - Sales;
        }
        else
        {
            // Keys don't match, so this is the first week
            Row.WeekSales = Row.Sales;
        }

        // Store current row values in the variables for the next row
        Bike = Row.Bike;
        WeekNr = Row.WeekNr;
        Sales = Row.Sales;
    }
}

or VB.net code:

' VB.net Code
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper
Imports Microsoft.SqlServer.Dts.Runtime.Wrapper

<microsoft .sqlserver.dts.pipeline.ssisscriptcomponententrypointattribute=".sqlserver.dts.pipeline.ssisscriptcomponententrypointattribute"> _
<clscompliant false="false"> _
Public Class ScriptMain
    Inherits UserComponent

    ' Variables to store the previous row
    Dim Bike As String = ""
    Dim WeekNr As Integer = 0
    Dim Sales As Integer = 0

    Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
        ' Compare current key with previous key
        If (Row.Bike = Bike) Then
            ' Keys match, so you can compare current sales with previous sales
            Row.WeekSales = Row.Sales - Sales
        Else

            ' Keys don't match, so this is the first week
            Row.WeekSales = Row.Sales
        End If

        ' Store current row values in the variables for the next row
        Bike = Row.Bike
        WeekNr = Row.WeekNr
        Sales = Row.Sales
    End Sub
End Class

5) The result
I added an empty Derived Column and a Data Viewer for testing purposes.
The result

No comments:

Post a Comment

Please use the SSIS MSDN forum for general SSIS questions that are not about this post. I'm a regular reader of that forum and will gladly answer those questions over there.

All comments are moderated manually to prevent spam.

Related Posts Plugin for WordPress, Blogger...