As seen below the two queries, we find that they both work well. Then I am confused why should we ever use BETWEEN because I have found that BETWEEN behaves differently in d
BETWEEN
can help to avoid unnecessary reevaluation of the expression:
SELECT AVG(RAND(20091225) BETWEEN 0.2 AND 0.4)
FROM t_source;
---
0.1998
SELECT AVG(RAND(20091225) >= 0.2 AND RAND(20091225) <= 0.4)
FROM t_source;
---
0.3199
t_source
is just a dummy table with 1,000,000
records.
Of course this can be worked around using a subquery, but in MySQL
it's less efficient.
And of course, BETWEEN
is more readable. It takes 3
times to use it in a query to remember the syntax forever.
In SQL Server
and MySQL
, LIKE
against a constant with non-leading '%'
is also a shorthand for a pair of >=
and <
:
SET SHOWPLAN_TEXT ON
GO
SELECT *
FROM master
WHERE name LIKE 'string%'
GO
SET SHOWPLAN_TEXT OFF
GO
|--Index Seek(OBJECT:([test].[dbo].[master].[ix_name_desc]), SEEK:([test].[dbo].[master].[name] < 'strinH' AND [test].[dbo].[master].[name] >= 'string'), WHERE:([test].[dbo].[master].[name] like 'string%') ORDERED FORWARD)
However, LIKE
syntax is more legible.
Personally, I wouldn't use BETWEEN
, simply because there seems no clear definition of whether it should include, or exclude, the values which serve to bound the condition, in your given example:
SELECT *
FROM emplyees
WHERE salary between 5000 AND 15000;
The range could include the 5000 and 15000, or it could exclude them.
Syntactically I think it should exclude them, since the values themselves are not between the given numbers. But my opinion is precisely that, whereas using operators such as >=
is very specific. And less likely to change between databases, or between incremements/versions of the same.
Edited in response to Pavel and Jonathan's comments.
As noted by Pavel, ANSI SQL (http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt) as far back as 1992, mandates the end-points should be considered within the returned date and equivalent to X >= lower_bound AND X <= upper_bound
:
8.3
Function Specify a range comparison. Format <between predicate> ::= <row value constructor> [ NOT ] BETWEEN <row value constructor> AND <row value constructor> Syntax Rules 1) The three <row value constructor>s shall be of the same degree. 2) Let respective values be values with the same ordinal position in the two <row value constructor>s. 3) The data types of the respective values of the three <row value constructor>s shall be comparable. 4) Let X, Y, and Z be the first, second, and third <row value con- structor>s, respectively. 5) "X NOT BETWEEN Y AND Z" is equivalent to "NOT ( X BETWEEN Y AND Z )". 6) "X BETWEEN Y AND Z" is equivalent to "X>=Y AND X<=Z".
BETWEEN in T-SQL supports NOT operator, so you can use constructions like
WHERE salary not between 5000 AND 15000;
In my opinion it's more clear for a human then
WHERE salary < 5000 OR salary > 15000;
And finally if you type column name just one time it gives you less chances to make a mistake
I'd better use the 2nd one, as you always know if it's <= or <
In SQL, I agree that BETWEEN
is mostly unnecessary, and can be emulated syntactically with 5000 <= salary AND salary <= 15000
. It is also limited; I often want to apply an inclusive lower bound and an exclusive upper bound: @start <= when AND when < @end
, which you can't do with BETWEEN
.
OTOH, BETWEEN is convenient if the value being tested is the result of a complex expression.
It would be nice if SQL and other languages would follows Python's lead in using proper mathematical notation: 5000 <= salary <= 15000
.
One small tip that wil make your code more readable: use < and <= in preference to > and >=.