I asked earlier if there would ever be any invoice number that does not start with A. There were a couple reasons for this question.
If ALL invoices start with A, then remove it from the data and change the invoice number column to an integer.
If you have invoice numbers other than A, I would encourage a long term fix. Obviously, the letter prefix has a meaning, and so do the numbers. So, you are storing 2 different pieces of data in the same column. The violates database normalization rules. If you separate the data in to two columns, it is EXTREMELY EASY to concatenate them together for display purposes, but you will also be able to work with the data separate, if need be.
Now, let's look at the suggestion made earlier...
Code:
DECLARE @tbl TABLE (items VARCHAR(50))
INSERT INTO @tbl VALUES ('A10710')
INSERT INTO @tbl VALUES ('A10711')
INSERT INTO @tbl VALUES ('A10730')
INSERT INTO @tbl VALUES ('A1072')
INSERT INTO @tbl VALUES ('A1073')
SELECT * FROM @tbl
WHERE REPLACE(items,'A','') BETWEEN 10710 AND 10730
Specifically, let's look at the where clause. The operator is BETWEEN. On the left side, we have a varchar column (items). We replace the letter A with nothing, but it's still a string. On the right, we have a couple of integers. When SQL Server compares a string to an integer, it first converts the string to an integer and then performs the comparison as though it were an integer.
In this case, it can cause a problem if you have invoice numbers that have characters other than A (for example, B). There is an interesting 'trick' that you can use to prevent this potential problem, AND also make the query faster.
For example, take a look at this code....
Code:
DECLARE @tbl TABLE (items VARCHAR(50))
INSERT INTO @tbl VALUES ('A10710')
INSERT INTO @tbl VALUES ('A10711')
INSERT INTO @tbl VALUES ('A10730')
INSERT INTO @tbl VALUES ('A1072')
INSERT INTO @tbl VALUES ('A1073')
INSERT INTO @tbl VALUES ('[!]B1072[/!]')
INSERT INTO @tbl VALUES ('[!]B1073[/!]')
SELECT * FROM @tbl
WHERE REPLACE(items,'A','') BETWEEN 10710 AND 10730
If you run the code above, you will get an error.
[tt][red]Conversion failed when converting the varchar value 'B1072' to data type int.[/red][/tt]
But... with this trick...
Code:
SELECT * FROM @tbl
WHERE [!]items like 'A%'[/!]
And REPLACE(items,'A','') BETWEEN 10710 AND 10730
This will prevent the error message with the given data, but it still isn't completely safe because a value of 'AX123' will satisfy the like comparison but still fail the integer conversion. If all of your invoice numbers start with a single character followed by all numbers, then the like comparison should work ok for you.
There is another (hidden) benefit of the like comparison. Since the comparison is based on the beginning of the string, SQL Server would be able to use an index on the items column to quickly locate the data. Specifically... an index seek would be performed instead of an index scan. With a large table, the difference in time could be huge.
-
George
"The great things about standards is that there are so many to choose from." - Fortune Cookie Wisdom