- Community Pick
- Experts Exchange Approved
Not so long ago, there was a fairly tricky question on Experts Exchange to do with unstringing a field, and some very good answers. Not wanting to be left out of the "fray", I submitted one of my old tricks. Despite the code being around for a while in various guises, my posting was met with intrigue and various superlatives. Naturally, I felt rather EElated at the response, though, cannot take all the credit.
So, I thought I would share some of those tricks that center around the use of a rather special table in MS SQL Server known as spt_values in the master database.
First, what is spt_values ?
It has been around since the beginning, it is not a system table, but is very much a part of SQL. It is rather simple, it is Microsoft's very own "look up" table for all those system type things (determined by the TYPE column) where you need a name. More importantly, it is probably always resident in memory.
Let's have a quick peek, and please scroll through the list after you have run the first select command, and you will see quite a variety of "names" which are actually held as numbers within the MS systems...
So, what can we do with a list of numbers ?
Well, in this article, we can unstring a delimited field, and we can create a virtual calendar. Both of which might normally involve creating a function or a special table...
Before we get into some examples, we are going to need some data. So, let's create a simple series of tables for Sales and Purchases of Inventory Items. These inventory items have a list of options that can be selected, and it is that list that we want to expand.
Right, so now we have some data, we are ready to begin...
First we will "normalise" the Raw Materials into a precise list of all possible selections. We will do this by "unstringing" the delimited string of options.
Can you see what we did ?
We are using our list of numbers as pointers to the delimiter character. The first part is easy enough, we simply join Inventory items to their list of options. The second part is then using our list of numbers to point to the individual occurrences of the delimiter (hence duplicating the rows for however many delimiters there are). Our select statement takes care of extracting the individual choices by using the value of the pointer as part of the substring command.
Not the most efficient, but no need for any special functions to be written and very handy in some more complex select statements, where it is all taken care of in a single select.
Now there is a "gotcha". Considering our range of numbers has a maximum value of 2047, our string cannot be longer unless we go and create our own "numbers" table.
The next example is based around datetimes. Ever needed a list of days in a month, or, the hours in a day ? Well it is pretty easy to create dynamically with a list of numbers at our disposal. Have a look at the next two select statements using "getdate()". We will do something similar for the next example using our sample data.
So, let's put that to good use and show the sales and purchases (i.e., inventory movement) throughout the month. Suppose we are provided the parameter @P as a month / year string. We could use it directly, but better to cast as the start and end of month as appropriate.
Yeah, yeah, this could have been done with a CTE Recursive query, except that sometimes, the recursive part is not available for calculating a calendar, and using the above method we can still get our virtual calendar.
So, using a list of numbers can be very handy. The fact that Microsoft supplies them is even handier. Hope you find some inspiration and possible uses for spt_values in your own work.
by: mwvisa1 on 2009-10-14 at 19:48:38ID: 4239
Mark, nice article.
Made a link from my date article in response to a discussion comment and realized I never officially voted yes above -- you have my vote now!