tags:

views:

551

answers:

11

As seen in below 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 different databases as found in w3school

SELECT *
FROM emplyees
WHERE salary between 5000 AND 15000;

SELECT *
FROM emplyees
WHERE salary >= 5000
AND salary <= 15000;
A: 

I'd better use the 2nd one, as you always know if it's <= or <

Dani
If you know SQL properly you know what BETWEEN does. Otherwise, you're a programmer hacking about in SQL - get a DB developer to write your SQL for you!
John
Should I fire the current programmer ? or can I let him use syntax that he understands, instead of getting a new guy to do the job ?
Dani
+4  A: 

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".
David Thomas
SQL Server, Oracle, MySQL, Postgres... all consider the endpoints to be inclusive.
OMG Ponies
What do you mean by "no clear definition"? ANSI SQL has it.
Pavel Minaev
The SQL standard mandates that the end points are included in the range.
Jonathan Leffler
OMG Ponies: Ok, but not natural language rules. And this fact conflicts with suggetion about "more readable code".
ThinkJet
My apologies, @Pavel and @Jonathan, I was unaware of its definition in the ANSI SQL; and offered my answer in some ignorance, my thanks for the correction. Edited-in.
David Thomas
Also, @Pavel and Jonathan, +1 for your help in straightening me out =)
David Thomas
Just learn how to use the langauge... '==' Vs '=' looks confusing to a C coder initially and '==' Vs '===' in JavaScript... but that doesn't mean you shouldn't learn them and use them.
John
A: 

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 >=.

Marcelo Cantos
That's purely a personal preference. I don't see '<=' being hard to read.
John
I assume you mean '>=', since '<=' is the one I prefer. The reason I prefer to use the less-than operators is that it ensures a consistent reading from smallest on the left, to largest on the right. It makes visually scanning such logic noticeably faster.
Marcelo Cantos
+6  A: 

The version with "between" is easier to read. If I were to use the second version I'd probably write it as

5000 <= salary and salary <= 15000

for the same reason.

Rich
+1 Range checks are SO much easier to read with only less-than!
Andomar
Easy to read, but no easy to understand. Imagine that you use BETWEEN for STRING or DATETIME values ...
ThinkJet
sorry Kev, but I don't think that was a typo. It doesn't make sense as it is now...
Radu094
I think you meant 5000 <= salary and salary <= 15000Shoulda used BETWEEN. :-)
Bob Jarvis
That is indeed what I meant, so that was what I wrote. I also don't see what the problem is using "between" with types other than numeric types as long as they have an ordering.
Rich
+1  A: 

If the endpoints are inclusive, then BETWEEN is the preferred syntax.

Less references to a column means less spots to update when things change. It's the engineering principle, that less things means less stuff can break.

It also means less possibility of someone putting the wrong bracket for things like including an OR. IE:

WHERE salary BETWEEN 5000 AND (15000
  OR ...)

...you'll get an error if you put the bracket around the AND part of a BETWEEN statement. Versus:

WHERE salary >= 5000
 AND (salary <= 15000
  OR ...)

...you'd only know there's a problem when someone reviews the data returned from the query.

OMG Ponies
The example with brackets was nice one .But regarding the inclusive Between ,it actually behaves differently in different database as I found from http://www.w3schools.com/sql/sql%5Fbetween.asp
Thunder
It's about common bracket formatting rules, not only for BETWEEN statement. Simple format text of your queries propelry and there is no problem.
ThinkJet
@Thunder: If you check the respective database documentation, you'll find that it is consistently implemented (being ANSI-92) in Oracle, SQL Server, MySQL, Postgres, SQLite.
OMG Ponies
A: 

Semantically, the two expressions have the same result.

However, BETWEEN is a single predicate, instead of two comparison predicates combined with AND. Depending on the optimizer provided by your RDBMS, a single predicate may be easier to optimize than two predicates.

Although I expect most modern RDBMS implementations should optimize the two expressions identically.

Bill Karwin
+4  A: 

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

bniwredyc
But NOT BETWEEN very bad for performance on big tables
ThinkJet
About "more clear for human" : "in the space separating (two points, objects, etc.)". Not inclusive as in ANSI standard. Citatation from http://dictionary.reference.com/browse/BETWEEN? . NOT BETWEEN requires even more mental acrobatics.
ThinkJet
You meant "WHERE salary < 5000 OR salary > 15000"
Doc Brown
@Doc Brown - yes, thank you
bniwredyc
@ThinkJet ok, for almost human like me (%
bniwredyc
@bniwredyc : Ok. I prefer mathematical notation in this case. There are 10 type of people ... http://stackoverflow.com/questions/234075/what-is-your-best-programmer-joke/234128#234128 :-)
ThinkJet
+14  A: 

Using BETWEEN has extra merits when the expression that is compared is a complex calculation rather than just a simple column; it saves writing out that complex expression twice.

Jonathan Leffler
I think it's the right answer
bniwredyc
Better coding style not always shorter style ...
ThinkJet
+19  A: 

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.

Quassnoi
Good reason to use it, but very specific (e.g. useful for comparation with current timestamps) and limited to only one expression in where, which can produce more errors. Such things must be passed into query as parameters.
ThinkJet
The nature of BETWEEN makes it useful for a rigid range. But if that is acceptable, we get better performance. If we need flexible range with more conditioning, we could hardly neglect the symbols (<,<=,>,>= or so). Thanks @Quassnio for putting comparitive analysis in terms of query time.
sangam
`@sangam`: this is not the query time, it's the query correctness :)
Quassnoi
@Quassnoi, thanks a lot for correcting me. I will edit my answers too.
sangam
And further, the above comment will be: The nature of BETWEEN makes it useful for a rigid range. But if that is acceptable, we get more accuracy. If we need flexible range with more conditioning, we could hardly neglect the symbols (<,<=,>,>= or so). Thanks @Quassnio for putting comparitive analysis in terms of query correctness.
sangam
+4  A: 

I vote @Quassnoi - correctness is a big win.

I usually find literals more useful than the syntax symbols like <, <=, >, >=, != etc. Yes, we need (better, accurate) results. And at least I get rid of probabilities of mis-interpreting and reverting meanings of the symbols visually. If you use <= and sense logically incorrect output coming from your select query, you may wander some time and only arrive to the conclusion that you did write <= in place of >= [visual mis-interpretation?]. Hope I am clear.

And aren't we shortening the code (along with making it more higher-level-looking), which means more concise and easy to maintain?

SELECT * 
FROM emplyees 
WHERE salary between 5000 AND 15000; 



SELECT * 
FROM emplyees 
WHERE salary >= 5000 AND salary <= 15000;

First query uses only 10 words and second uses 12!

sangam
A: 

worse if it's

  SELECT id FROM entries 
  WHERE 
     (SELECT COUNT(id) FROM anothertable WHERE something LEFT JOIN something ON...) 
     BETWEEN entries.max AND entries.min;

Rewrite this one with your syntax without using temporary storage.

SF.