Robby on Rails: Using BETWEEN for SQL comparisonsthoughts.sort_by{|t| t[:topic]}.collect tag:www.robbyonrails.com,2005:TypoTypo2009-11-14T15:00:20-05:00Robby Russellurn:uuid:e7b6f3bd-81d1-4cdb-bf95-ae4e9f97cdf52009-11-14T14:55:00-05:002009-11-14T15:00:20-05:00Using BETWEEN for SQL comparisons<p>Recently, <a href="http://eddorre.com/">Carlos</a>, suggested that I should start sharing some basic <span class="caps">SQL</span> tips that help with performance and/or general usage. I recently came across some code that I didn’t like to read and/or write. For example, let’s take the following…</p>
<pre><code>
SELECT * FROM brochures WHERE published_at <= now() AND archived_at >= now()
</code></pre>
<p>Essentially, this is pulling back some data <code>WHERE</code> the the brochures are considered published. (<em>We have a project that allows people to manage their brochure launch dates ahead of time.</em>) In fact, in this project, we have no less than 6-8 dates in the database that we’re comparing data on and it’s easy to get lost in the logic when trying to understand it.</p>
<p>Now, there isn’t anything inheriently wrong with how this condition is constuctued. As a matter of personal taste, I find it annoying to mentally parse. Also, I find having to write <code>now()</code> more than once in a <code>WHERE</code> clause to feel like I’m repeating myself.</p>
<p>Read it outloud…</p>
<blockquote>
<p>“WHERE the brochures published at date is less than and/or equal to right now <span class="caps">AND</span> the archived date is greater than and/or equal to now.”</p>
</blockquote>
<p>Who talks like that?</p>
<p>Luckily, there is a better and in my opinion, a more readable way to express this is with the <span class="caps">BETWEEN</span> construct in <span class="caps">SQL</span>. (<a href="http://www.postgresql.org/docs/current/static/functions-comparison.html">postgresql docs</a>, <a href="http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_between">mysql docs</a>)</p>
<pre><code>
SELECT * FROM brochures WHERE now() BETWEEN published_at AND archived_at
</code></pre>
<p>Let’s read this outloud…</p>
<blockquote>
<p>“WHERE the current date is <em>between</em> the published at and archived at dates.”</p>
</blockquote>
<p>This sounds more natural to me.</p>
<p>Additionally, you can also do the inverse with <code>NOT</code>.</p>
<pre><code>
SELECT ... WHERE now() NOT BETWEEN brochures.published_at AND brochures.archive_at
</code></pre>
<p>Remember kids, <em>“code is for humans first and computers second.”</em>—Martin Fowler</p><p>Recently, <a href="http://eddorre.com/">Carlos</a>, suggested that I should start sharing some basic <span class="caps">SQL</span> tips that help with performance and/or general usage. I recently came across some code that I didn’t like to read and/or write. For example, let’s take the following…</p>
<pre><code>
SELECT * FROM brochures WHERE published_at <= now() AND archived_at >= now()
</code></pre>
<p>Essentially, this is pulling back some data <code>WHERE</code> the the brochures are considered published. (<em>We have a project that allows people to manage their brochure launch dates ahead of time.</em>) In fact, in this project, we have no less than 6-8 dates in the database that we’re comparing data on and it’s easy to get lost in the logic when trying to understand it.</p>
<p>Now, there isn’t anything inheriently wrong with how this condition is constuctued. As a matter of personal taste, I find it annoying to mentally parse. Also, I find having to write <code>now()</code> more than once in a <code>WHERE</code> clause to feel like I’m repeating myself.</p>
<p>Read it outloud…</p>
<blockquote>
<p>“WHERE the brochures published at date is less than and/or equal to right now <span class="caps">AND</span> the archived date is greater than and/or equal to now.”</p>
</blockquote>
<p>Who talks like that?</p>
<p>Luckily, there is a better and in my opinion, a more readable way to express this is with the <span class="caps">BETWEEN</span> construct in <span class="caps">SQL</span>. (<a href="http://www.postgresql.org/docs/current/static/functions-comparison.html">postgresql docs</a>, <a href="http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_between">mysql docs</a>)</p>
<pre><code>
SELECT * FROM brochures WHERE now() BETWEEN published_at AND archived_at
</code></pre>
<p>Let’s read this outloud…</p>
<blockquote>
<p>“WHERE the current date is <em>between</em> the published at and archived at dates.”</p>
</blockquote>
<p>This sounds more natural to me.</p>
<p>Additionally, you can also do the inverse with <code>NOT</code>.</p>
<pre><code>
SELECT ... WHERE now() NOT BETWEEN brochures.published_at AND brochures.archive_at
</code></pre>
<p>Remember kids, <em>“code is for humans first and computers second.”</em>—Martin Fowler</p>