With so many solutions, how can you tell which solutions are most likely to help you and which ones are not? To provide you with a tool to use, we rate our solutions based on various elements that most accurately determine if a solution is a quality solution. To explain what factors affect the solution rating, here are the elements we take into consideration when formulating our solution rating.
The Grade of the Solution
The Zone Rank of the Expert Providing the Solution
The Number of Author and Expert Comments
The Number of Experts Contributing
The Feedback of the Community
Your Input Matters Because of the way the system is set up, the most important variable in this equation is you. As a member of Experts Exchange, you are able to cast your vote on the quality of the solutions in regard to how complete, accurate, helpful and easy to understand each solution is. When you provide your feedback, each rating is adjusted accordingly. So, if you see a solution that has a poor rating that you think is a good solution, let us know by rating it. As you do, the rating will be adjusted and will become more accurate for other members of our site.
If you have any suggestions that you would like to make for our rating system, please ask a question in the Suggestions Zone of Community Support.
I am usually pretty handy with basic SQL operations, but I have a need for an operation that requires some sort of loop and/or cursor/table variable/temp table approach that needs to be as efficient as possible.
Here is what I need to do, in SQL Server 2000:
1. I have two tables, one each in two databases on the same server.
DatabaseA.dbo.ShiftHrs_Update -------------------------------------------------------------------- shift_id uniqueidentifier BlockStart datetime BlockDur int pattern_id uniqueidentifier
This table has 1 to 7 records for each shift; each record represents the working hours at a particular company location. Each location may be open different days of the week (and thus a limit of 7 records for any given shift_id), and be open during various hours on the days they are open. BlockStart specifies the start date/time of the shift, and BlockDur is the length of the shift in seconds. The dates are all within a "reference week" that started Sunday 4 Jan 2004.
This table is used to spread a forecasted weekly work requirement throughout a day, split into half-hour intervals. Thus, if I want to spread the workload evenly throughtout open hours, I would have a record for each half-hour interval inside the shift's open hours, with the same sample_value for each record. The dates are all within a "reference week" that started Sunday 4 Jan 2004.
2. For each record in DatabaseA.dbo.ShiftHrs_Update, I have to insert records in DatabaseB.dbo.pattern_values such that for the time period specified in DatabaseA.dbo.ShiftHrs_Update I have every half-hour interval covered in DatabaseB.dbo.pattern_values. For example, if the record in DatabaseA.dbo.ShiftHrs_Update is:
<shift_id>, 2004-01-05 09:00:00, 28800, <pattern_id> (that is, Monday from 9am - 5pm)
Then I would need to insert the following in DatabaseB.dbo.pattern_values:
(Note that there is no record for the 5:00 pm interval, because that is the end time of the shift that day.)
Any help will be greatly appreciated. If anything above is unclear, please do not hesitate to ask for clarification. I will be away for a few hours, but will be checking back in in the early afternoon during USA Eastern time.
You've pretty much got all you need without using a loop. Just alter the pattern_values table to contain the actual hourly timeslot, then join on the pattern_id
For example (making assumptions here but you can correct me)
Now you just join those tables on pattern_id, and have a calc that adds pattern_values.sample_date to ShiftHrs_Update.BlockStart
SELECT P.pattern_id, DATEADD(mi,U.BlockStart,P.Shift_Minutes), U.Sample_Value FROM pattern_values P INNER JOIN ShiftHrs_Update U ON P.pattern_id = U.pattern_id
On a different note, I suggest you change your FLOAT to a NUMERIC unless you have a good reason.
Also I avoid the use of uniqueidentifier unless you want this to be unique accross databases worldwide.. just my preference.
Anyway I've made assumption about exactly what dependencies and functions the tables server and you'll probably need to correct me.
The main point is that you can avoid loops by use of one to many joins
Also if you find you're doing this kind of things a lot, its worth either creating a special work table, or a special work UDF that accepts parameters and returns a suitable recordset to join to.
<<that requires some sort of loop and/or cursor/table variable/temp table approach that needs to be as efficient as possible.>> As nmcdermaid politely pointed out, *Looping* and *efficient* are contradictory words in SQL Server's realm...
Racimo wrote... > As nmcdermaid politely pointed out, *Looping* and *efficient* are contradictory words in SQL Server's realm...
Indeed!
Yesterday afternoon I started trying some approaches using a "calendar" table, similar to what nmcdermaid describes, and I started seeing that the solution was much, much easier than I thought. For some reason, I had developed a sort of tunnel vision that was closing off other ways of seeing the problem.
As for the design of "DatabaseB", with the usage of uniqueidentifier and float columns... I have no control over that one. DatabaseB follows the schema of another designer and cannot be altered. I have total control over DatabaseA, but of course some of my choices there are contingent on the (in my opinion, sometimes questionable) choices made by the designers of DatabaseB. So, I am stuck with uniqueidentifier for the foreign keys, and float for the patern weights.
<<For some reason, I had developed a sort of tunnel vision that was closing off other ways of seeing the problem.>> If that can make you feel better, keep in mind that thinking in terms of sets as opposed to think procedurally(looping) is anything but natural or intuitive. It is however much more adequate to get the best out of database systems.