Question

I have pored over numerous questions and answers but can't seem to find a solution that works for me. Here is what I am trying to do:

Say I have table called "Store" that holds Store IDs, store names, and the annual sales of that store. The business wants each store to increase it's sales by 50% over the next year, and wants to calculate monthly target sales amounts that each store needs to reach to make the 50% increase value. For example, if store number 5 had $1000 in sales last year, the target for the end of the next year would be $1500. And to reach that, the amount for each month would need to be something like $1042, $1084, $1126... $1500.

What I am trying to do is insert 12 records for each store into a 'monthly plan fact' table. I am trying to select a store from the Store table, grab the annual sales amount, then do a loop inside that where I calculate what each month value would be so I can insert it into the 'monthly plan fact' table, then select the next store from the store table... and so on. As a C# developer, it seems a very simple task that could be accomplished with a 'for each' style loop with another 'for' loop inside it.

But I cannot for the life of me figure out how to do this in SQL. I know about temp tables, but I can't seem to figure out how to get multiple rows inserted into my 'monthly plan fact' table using the records from the Store table, and the values calculated in the loop to determine the monthly plan values. I've read some on cursors, but it seems that most people advise against them in the SQL community, so I am at a loss on this one.

Was it helpful?

Solution 2

In Sql you really should try to avoid using loops. Instead, you should use a set-based approach. This post (first answer) has a good link on why you shouldn't do it, then an example that could help you do it. Take a look at using a CURSOR instead.

@paqogomez was right :)

OTHER TIPS

The T-SQL below shows how to really easily get the sales targets for each store for each month. I've included two columns here: one called 'salesTargetYourExample' where we have a pattern like 1042, 1084, ... for sales targets and one called 'linearGrowthSales' where we have the new annual sales target (e.g. 1500 for the store that made 1000 last year) and simply look at what sales should be at the end of each month to reach that target assuming linear growth).

The short answer though is to always think in terms of sets and set based operations when working with databases. Don't think in terms of loops

-- Create the store table
create table dbo.Store
(
    storeId int not null primary key clustered,
    storeName varchar(100) not null,
    annualSales money not null
);

-- Populate the data in the store table
insert into dbo.Store(storeId,storeName,annualSales)
values (1, 'My first store', 2000),
    (5, 'Store number five', 1000),
    (6, 'The sixth store', 2500);


-- Get the sales targets for each store on a monthly basis
select s.storeId, s.storeName, months.mth,
    (s.annualSales * 0.5 * months.mth/12) + s.annualSales as salesTargetYourExample,
    s.annualSales * 1.5 * months.mth/12 as linearGrowthSales
from dbo.Store as s
cross apply
(
    values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)
) as months(mth)

In the event you choose to do a loop in SQL though its frowned upon but it does exist. Here is how its done. This is a more general answer about loops in SQL not specific to this question. Im hoping someone who is stuck and for whatever reason cant go the other way (set based) can benefit:

Declare @intCount as int
Declare @numberOfTimes as int

WHILE @intCount <= @numberoftimes

BEGIN

--Do something repetitive

END
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top