Calculating monthly billing total

  • Hello...

    I'm hoping that someone can help me calculate a monthly billing total. I'm writing a report where I need to account for a minimum price in the total bill. Not all of the records have a minimum and some of the records the minimum has been reached. I'm trying the following...LastMonthsTotal * Price + Minimum (if minimum exists) and if the Minimum exists and has already been reached...I don't want to add it to the TotalMonthlyBill.

    Here's a sample of the data...

    IF OBJECT_ID('TempDB..#MonthlyBilling','U') IS NOT NULL

    DROP TABLE #MonthlyBilling

    CREATE TABLE [dbo].[#MonthlyBilling](

    [Recordid] [int] identity NOT NULL,

    [Partner] varchar (100) NOT NULL,

    [LastMonthsTotal] [int] NULL,

    [Price] [money] NULL,

    [Minimum] [money] NULL,

    [TotalMonthlyBill] [money] NULL,

    CONSTRAINT [pk_MonthlyBilling] PRIMARY KEY CLUSTERED

    (

    [Recordid] ASC

    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY

    = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

    ) ON [PRIMARY]

    SET IDENTITY_INSERT #MonthlyBilling ON

    INSERT INTO #MonthlyBilling

    (Recordid, Partner, LastMonthsTotal, Price, Minimum,

    TotalMonthlyBill)

    SELECT '101','Some Company 1','1000','0.50','175.00',NULL UNION ALL

    SELECT '102','Some Company 2','1000','1.00','175.00',NULL UNION ALL

    SELECT '103','Some Company 3','1000','1.00','0.00',NULL UNION ALL

    SELECT '104','Some Company 4',null,'1.00','175.00',NULL UNION ALL

    SELECT '105','Some Company 5',null,'0.00','100.00',NULL UNION ALL

    SELECT '106','Some Company 6',null,'0.00','100.00',NULL UNION ALL

    SELECT '107','Some Company 7','50','.50','50.00',NULL

    SET IDENTITY_INSERT #MonthlyBilling OFF

    Thanks in advance!

  • I've almost got it figured out. Here's what I came up with. Please note recordid 107...that's where I'm just not getting it.

    DECLARE @recordid varchar(50), @sql2 varchar(1000)

    DECLARE crs CURSOR FOR

    SELECT recordid FROM #MonthlyBilling

    OPEN crs

    FETCH NEXT FROM crs INTO @recordid

    WHILE @@FETCH_STATUS = 0

    BEGIN

    SET @sql2 ='

    UPDATE #MonthlyBilling

    SET TotalMonthlyBill =

    (CASE

    WHEN LastMonthsTotal * Price + Minimum > Minimum

    THEN LastMonthsTotal * Price

    WHEN LastMonthsTotal * Price + Minimum < Minimum

    THEN Minimum

    WHEN LastMonthsTotal = 0 or LastMonthsTotal IS NULL

    THEN Minimum

    END)

    WHERE Recordid = '''+@recordid+''''

    EXEC (@sql2)

    FETCH NEXT FROM crs INTO @recordid

    END

    CLOSE crs

    DEALLOCATE crs

    SELECT * FROM #MonthlyBilling

  • dave b (5/2/2009)


    Hello...

    I'm hoping that someone can help me calculate a monthly billing total. I'm writing a report where I need to account for a minimum price in the total bill. Not all of the records have a minimum and some of the records the minimum has been reached. I'm trying the following...LastMonthsTotal * Price + Minimum (if minimum exists) and if the Minimum exists and has already been reached...I don't want to add it to the TotalMonthlyBill.

    Here's a sample of the data...

    IF OBJECT_ID('TempDB..#MonthlyBilling','U') IS NOT NULL

    DROP TABLE #MonthlyBilling

    CREATE TABLE [dbo].[#MonthlyBilling](

    [Recordid] [int] identity NOT NULL,

    [Partner] varchar (100) NOT NULL,

    [LastMonthsTotal] [int] NULL,

    [Price] [money] NULL,

    [Minimum] [money] NULL,

    [TotalMonthlyBill] [money] NULL,

    CONSTRAINT [pk_MonthlyBilling] PRIMARY KEY CLUSTERED

    (

    [Recordid] ASC

    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY

    = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

    ) ON [PRIMARY]

    SET IDENTITY_INSERT #MonthlyBilling ON

    INSERT INTO #MonthlyBilling

    (Recordid, Partner, LastMonthsTotal, Price, Minimum,

    TotalMonthlyBill)

    SELECT '101','Some Company 1','1000','0.50','175.00',NULL UNION ALL

    SELECT '102','Some Company 2','1000','1.00','175.00',NULL UNION ALL

    SELECT '103','Some Company 3','1000','1.00','0.00',NULL UNION ALL

    SELECT '104','Some Company 4',null,'1.00','175.00',NULL UNION ALL

    SELECT '105','Some Company 5',null,'0.00','100.00',NULL UNION ALL

    SELECT '106','Some Company 6',null,'0.00','100.00',NULL UNION ALL

    SELECT '107','Some Company 7','50','.50','50.00',NULL

    SET IDENTITY_INSERT #MonthlyBilling OFF

    Thanks in advance!

    Based on the data provided, what are the expected results?

  • Thanks for the reply Lynn!

    I'm trying to update the [TotalMonthlyBill] with the [Minimum] if the [Minimum] [Minimum]...I only want the results of (LastMonthsTotal * Price). Make sense?

    If you run that cursor you'll see that recordid 107 is only calculating the (LastMonthsTotal * Price) as $25.00...but the [Minimum] for this record is $50.00. So the [TotalMonthlyBill] for recordid 107 should be $50.00.

    Am I just missing something simple? The rest of the records are correct.

    Dave

  • Your criteria is wrong. You shouldn't add minimum to the total and the price because in cases there there is anything >0, it will always exceed the minimum which will not give you what you want.

    Also, there is absolutely no need for a cursor to do this. In SQL Server, cursors and most While Loops take a huge toll on performance and code readability.

    The following code should do what you want it to do and includes the test data you were very kind to include (very well done there, by the way, thanks)...

    [font="Courier New"]--===== Conditionally drop the test table

         IF OBJECT_ID('TempDB..#MonthlyBilling','U'IS NOT NULL

            DROP TABLE #MonthlyBilling

    --===== Create the test table

     CREATE TABLE dbo.#MonthlyBilling

            (

            Recordid         INT IDENTITY(1,1),

            Partner          VARCHAR(100) NOT NULL,

            LastMonthsTotal  INT          NULL,

            Price            MONEY        NULL,

            Minimum          MONEY        NULL,

            TotalMonthlyBill MONEY        NULL,

            CONSTRAINT pk_MonthlyBilling 

                       PRIMARY KEY CLUSTERED (Recordid ASC)

            )

    --===== Populate the test table with test data

        SET IDENTITY_INSERT #MonthlyBilling ON

     INSERT INTO #MonthlyBilling

            (RecordidPartnerLastMonthsTotalPriceMinimum)

     SELECT '101','Some Company 1','1000','0.50','175.00' UNION ALL

     SELECT '102','Some Company 2','1000','1.00','175.00' UNION ALL

     SELECT '103','Some Company 3','1000','1.00','0.00'   UNION ALL

     SELECT '104','Some Company 4',NULL  ,'1.00','175.00' UNION ALL

     SELECT '105','Some Company 5',NULL  ,'0.00','100.00' UNION ALL

     SELECT '106','Some Company 6',NULL  ,'0.00','100.00' UNION ALL

     SELECT '107','Some Company 7','50'  ,'.50' ,'50.00'

     

    SET IDENTITY_INSERT #MonthlyBilling OFF

    --===== Calculate and save the total monthly bill using the "minimum"

     UPDATE #MonthlyBilling

        SET TotalMonthlyBill CASE

                                   WHEN ISNULL(LastMonthsTotal,0) * Price >= Minimum

                                   THEN LastMonthsTotal Price

                                   WHEN ISNULL(LastMonthsTotal,0) * Price Minimum

                                   THEN Minimum

                               END

    --===== Display the results

     SELECT FROM #MonthlyBilling

    [/font]

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Jeff...Thank you so much! This works great.

    BTW...I just started reading your post about the "Tally" table.

    I am now officially on a quest to eliminate my cursors and loops. 🙂

  • dave b (5/2/2009)


    Jeff...Thank you so much! This works great.

    BTW...I just started reading your post about the "Tally" table.

    I am now officially on a quest to eliminate my cursors and loops. 🙂

    And you, Sir, just made my day. Thank you for the great feedback.

    Anytime you post a test table and data population script like you did for this post, you'll find people who will trip over each other trying to help you... especially if you need help eliminating cursors. I wish more people would take the time you did because it made my life a lot easier because I could focus on helping you. Thanks for taking the time to post correctly.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

Viewing 7 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic. Login to reply