Sometimes our techie-brains convert a concept clearly articulated in plain English into unnecessarily mathematically expressed code.
For example, "I want all records with an amount between 1000 and 1999" can become "x >= 1000 AND x <= 1999"
But modern RDBMS database systems give us an English equivalent that saves translating the concept "between" into "greater than or equal to this, and less than or equal to that."
It's the BETWEEN function, and it is the same across SQL Server, PostgreSQL, MySQL, and Oracle. Maybe others, too, but those are the ones that I have used in the past.
BETWEEN is of the form:
MyTestValue BETWEEN StartValue AND EndValue
It is an inclusive comparison, equivalent to using >= and <= So these generate the same results:
SELECT * FROM MyTable WHERE MyValue BETWEEN 100 AND 1000
vs
SELECT * FROM MyTable WHERE MyValue >= 100 AND MyValue <= 1000
What are the advantages of BETWEEN? It's a little less typing; it's more intuitive to understand, without losing any precision in the expression.
And it avoids angle-brackets. Which can sound trivial, but was an issue on a recent bug report I had to deal with. Here's the story:
One sub-system at my current place of work allows our clients to write their own SQL queries, to retrieve exactly the data they need for their specialized business purposes. The sub-system allows global and context-specific variables to be substituted at run-time. These variables are enclosed in angle-brackets, e.g. "<PAYMENTTYPE>"
In this bug report, a client's SQL worked on all her staff's work-stations except one. This one work-station was receiving an Invalid SQL error.
After some effort, I isolated the source of the error. Buried deep in the client's SQL was this Where-clause (some details changed to protect the client):
WHERE G.AccountNumber <> 0
AND ( (G.LastYrAmount >= 1000 AND G.LastYrAmount <= 1999.99)
OR (G.ThisYrAmount >= 1000 AND G.ThisYrAmount <= 1999.99) )
It's a pretty straight-forward Where-expression. But on the work-station of this one staff member, that condition was being sent to the database as:
WHERE G.AccountNumber <> 0
AND ( (G.LastYrAmount >= 1000 AND G.LastYrAmount = 1999.99)
OR (G.250.00 = 1000 AND G.ThisYrAmount <= 1999.99) )
It appeared that the sub-system was performing the variable substitution, replacing ThisYrAmount with its value, 250.00 The opening "<" was coming from "G.LastYrAmount <= 1999.99" and the closing ">" from "G.ThisYrAmount >= 1000"
The sub-system needs to be smart enough to recognize that, given all of the other items mixed in between the two angle-brackets, it is NOT dealing with a variable-replacement token.
And it is, everywhere but on this one work-station.
There is something deeper going on with the client's work-station, which may be an issue for another day. For now, by advising them to rewrite their query to use BETWEEN, we can eliminate the paired angle-brackets and therefore the misapplied variable replacement.
WHERE G.AccountNumber <> 0
AND ( (G.LastYrAmount BETWEEN 1000 AND 1999.99)
OR (G.ThisYrAmount BETWEEN 1000 AND 1999.99) )
A final note: the database backing this sub-system is Microsoft SQL Server, which has another alternative to eliminate the paired angle-brackets while still using the mathematical comparison operators. T-SQL and SQL Server provide Not-Greater and Not-Less operators, "!>" and "!<"
So the WHERE could be rewritten like this instead:
WHERE G.AccountNumber <> 0
AND ( (G.LastYrAmount >= 1000 AND G.LastYrAmount !> 1999.99)
OR (G.ThisYrAmount >= 1000 AND G.ThisYrAmount !> 1999.99) )
For example, "I want all records with an amount between 1000 and 1999" can become "x >= 1000 AND x <= 1999"
But modern RDBMS database systems give us an English equivalent that saves translating the concept "between" into "greater than or equal to this, and less than or equal to that."
It's the BETWEEN function, and it is the same across SQL Server, PostgreSQL, MySQL, and Oracle. Maybe others, too, but those are the ones that I have used in the past.
BETWEEN is of the form:
MyTestValue BETWEEN StartValue AND EndValue
It is an inclusive comparison, equivalent to using >= and <= So these generate the same results:
SELECT * FROM MyTable WHERE MyValue BETWEEN 100 AND 1000
vs
SELECT * FROM MyTable WHERE MyValue >= 100 AND MyValue <= 1000
What are the advantages of BETWEEN? It's a little less typing; it's more intuitive to understand, without losing any precision in the expression.
And it avoids angle-brackets. Which can sound trivial, but was an issue on a recent bug report I had to deal with. Here's the story:
One sub-system at my current place of work allows our clients to write their own SQL queries, to retrieve exactly the data they need for their specialized business purposes. The sub-system allows global and context-specific variables to be substituted at run-time. These variables are enclosed in angle-brackets, e.g. "<PAYMENTTYPE>"
In this bug report, a client's SQL worked on all her staff's work-stations except one. This one work-station was receiving an Invalid SQL error.
After some effort, I isolated the source of the error. Buried deep in the client's SQL was this Where-clause (some details changed to protect the client):
WHERE G.AccountNumber <> 0
AND ( (G.LastYrAmount >= 1000 AND G.LastYrAmount <= 1999.99)
OR (G.ThisYrAmount >= 1000 AND G.ThisYrAmount <= 1999.99) )
It's a pretty straight-forward Where-expression. But on the work-station of this one staff member, that condition was being sent to the database as:
WHERE G.AccountNumber <> 0
AND ( (G.LastYrAmount >= 1000 AND G.LastYrAmount = 1999.99)
OR (G.250.00 = 1000 AND G.ThisYrAmount <= 1999.99) )
It appeared that the sub-system was performing the variable substitution, replacing ThisYrAmount with its value, 250.00 The opening "<" was coming from "G.LastYrAmount <= 1999.99" and the closing ">" from "G.ThisYrAmount >= 1000"
The sub-system needs to be smart enough to recognize that, given all of the other items mixed in between the two angle-brackets, it is NOT dealing with a variable-replacement token.
And it is, everywhere but on this one work-station.
There is something deeper going on with the client's work-station, which may be an issue for another day. For now, by advising them to rewrite their query to use BETWEEN, we can eliminate the paired angle-brackets and therefore the misapplied variable replacement.
WHERE G.AccountNumber <> 0
AND ( (G.LastYrAmount BETWEEN 1000 AND 1999.99)
OR (G.ThisYrAmount BETWEEN 1000 AND 1999.99) )
So the WHERE could be rewritten like this instead:
WHERE G.AccountNumber <> 0
AND ( (G.LastYrAmount >= 1000 AND G.LastYrAmount !> 1999.99)
OR (G.ThisYrAmount >= 1000 AND G.ThisYrAmount !> 1999.99) )