<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
		>
<channel>
	<title>Comments on: Date Delta SQL &#8211; What is Wrong with this SQL Statement?</title>
	<atom:link href="http://hoopercharles.wordpress.com/2010/06/02/date-delta-sql-what-is-wrong-with-this-sql-statement/feed/" rel="self" type="application/rss+xml" />
	<link>http://hoopercharles.wordpress.com/2010/06/02/date-delta-sql-what-is-wrong-with-this-sql-statement/</link>
	<description>Miscellaneous Random Oracle Topics: Stop, Think, ... Understand</description>
	<lastBuildDate>Thu, 13 Jun 2013 22:46:43 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: Donatello Settembrino</title>
		<link>http://hoopercharles.wordpress.com/2010/06/02/date-delta-sql-what-is-wrong-with-this-sql-statement/#comment-1325</link>
		<dc:creator><![CDATA[Donatello Settembrino]]></dc:creator>
		<pubDate>Mon, 07 Jun 2010 13:31:53 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=2521#comment-1325</guid>
		<description><![CDATA[yes, the meaning of my answer is that 
apart from a date or a range returns a number]]></description>
		<content:encoded><![CDATA[<p>yes, the meaning of my answer is that<br />
apart from a date or a range returns a number</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sokrates</title>
		<link>http://hoopercharles.wordpress.com/2010/06/02/date-delta-sql-what-is-wrong-with-this-sql-statement/#comment-1324</link>
		<dc:creator><![CDATA[Sokrates]]></dc:creator>
		<pubDate>Mon, 07 Jun 2010 13:10:51 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=2521#comment-1324</guid>
		<description><![CDATA[&quot;1) from what I understand, it extracts the month from a date,&quot;

not only from a date, but also from an interval.]]></description>
		<content:encoded><![CDATA[<p>&#8220;1) from what I understand, it extracts the month from a date,&#8221;</p>
<p>not only from a date, but also from an interval.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Donatello Settembrino</title>
		<link>http://hoopercharles.wordpress.com/2010/06/02/date-delta-sql-what-is-wrong-with-this-sql-statement/#comment-1322</link>
		<dc:creator><![CDATA[Donatello Settembrino]]></dc:creator>
		<pubDate>Mon, 07 Jun 2010 12:42:54 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=2521#comment-1322</guid>
		<description><![CDATA[Charles
we should ask:

1) What does extract?
2) What I want as a result?

Reply

1) from what I understand, it extracts the month from a date, 
so for example, EXTRACT (MONTH FROM to_date (&#039;01-Mar-2010 &#039;)) = 3
then:
&lt;pre&gt;
SELECT EXTRACT(MONTH FROM to_date(&#039;01-mar-2010&#039;)) AS month1_ext ,
       EXTRACT(MONTH FROM to_date(&#039;05-jan-2010&#039;)) AS month2_ext
from dual

MONTH1_EXT             MONTH2_EXT              
---------------------- ---------------------- 
3                      1                     
&lt;/pre&gt;
it does is simply, 3 - 1 = 2, then in my opinion should not be 
used when we want the difference between two dates.

2)
if I have to do a temporal analysis on the data expressed in month, I have two situations, 
I think. Compare fixed dates (eg the first of each month), or to compare between any dates. 
In the first case, I should not have problems using Extract. In the second case, should be 
established a rule. Example: from 1 to 15 of every month as the first of this month, from 
16 onwards consider the first of next month.In the absence of rules, I do not think you can 
use Extract and I do not think it makes sense to have a difference between two 
dates in months(1.5 months is a month or two months ???).

Regards]]></description>
		<content:encoded><![CDATA[<p>Charles<br />
we should ask:</p>
<p>1) What does extract?<br />
2) What I want as a result?</p>
<p>Reply</p>
<p>1) from what I understand, it extracts the month from a date,<br />
so for example, EXTRACT (MONTH FROM to_date (&#8217;01-Mar-2010 &#8216;)) = 3<br />
then:</p>
<pre>
SELECT EXTRACT(MONTH FROM to_date('01-mar-2010')) AS month1_ext ,
       EXTRACT(MONTH FROM to_date('05-jan-2010')) AS month2_ext
from dual

MONTH1_EXT             MONTH2_EXT              
---------------------- ---------------------- 
3                      1                     
</pre>
<p>it does is simply, 3 &#8211; 1 = 2, then in my opinion should not be<br />
used when we want the difference between two dates.</p>
<p>2)<br />
if I have to do a temporal analysis on the data expressed in month, I have two situations,<br />
I think. Compare fixed dates (eg the first of each month), or to compare between any dates.<br />
In the first case, I should not have problems using Extract. In the second case, should be<br />
established a rule. Example: from 1 to 15 of every month as the first of this month, from<br />
16 onwards consider the first of next month.In the absence of rules, I do not think you can<br />
use Extract and I do not think it makes sense to have a difference between two<br />
dates in months(1.5 months is a month or two months ???).</p>
<p>Regards</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Charles Hooper</title>
		<link>http://hoopercharles.wordpress.com/2010/06/02/date-delta-sql-what-is-wrong-with-this-sql-statement/#comment-1303</link>
		<dc:creator><![CDATA[Charles Hooper]]></dc:creator>
		<pubDate>Sat, 05 Jun 2010 13:32:05 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=2521#comment-1303</guid>
		<description><![CDATA[Donatello,

That is certainly an improvement for the first day of the month:
&lt;pre&gt;
D1        D2        DATE_DELTA T
--------- --------- ---------- ------------------
01-JAN-10 02-JAN-10          1 0 years, 0 months.
01-JAN-10 03-JAN-10          2 0 years, 0 months.
01-JAN-10 04-JAN-10          3 0 years, 0 months.
01-JAN-10 05-JAN-10          4 0 years, 0 months.
01-JAN-10 06-JAN-10          5 0 years, 0 months.
01-JAN-10 07-JAN-10          6 0 years, 0 months.
01-JAN-10 08-JAN-10          7 0 years, 0 months.
01-JAN-10 09-JAN-10          8 0 years, 0 months.
01-JAN-10 10-JAN-10          9 0 years, 0 months.
01-JAN-10 11-JAN-10         10 0 years, 0 months.
01-JAN-10 12-JAN-10         11 0 years, 0 months.
01-JAN-10 13-JAN-10         12 0 years, 0 months.
01-JAN-10 14-JAN-10         13 0 years, 0 months.
01-JAN-10 15-JAN-10         14 0 years, 0 months.
01-JAN-10 16-JAN-10         15 0 years, 0 months.
01-JAN-10 17-JAN-10         16 0 years, 0 months.
01-JAN-10 18-JAN-10         17 0 years, 0 months.
01-JAN-10 19-JAN-10         18 0 years, 0 months.
01-JAN-10 20-JAN-10         19 0 years, 0 months.
01-JAN-10 21-JAN-10         20 0 years, 0 months.
01-JAN-10 22-JAN-10         21 0 years, 0 months.
01-JAN-10 23-JAN-10         22 0 years, 0 months.
01-JAN-10 24-JAN-10         23 0 years, 0 months.
01-JAN-10 25-JAN-10         24 0 years, 0 months.
01-JAN-10 26-JAN-10         25 0 years, 0 months.
01-JAN-10 27-JAN-10         26 0 years, 0 months.
01-JAN-10 28-JAN-10         27 0 years, 0 months.
01-JAN-10 29-JAN-10         28 0 years, 0 months.
01-JAN-10 30-JAN-10         29 0 years, 0 months.
01-JAN-10 31-JAN-10         30 0 years, 0 months.
01-JAN-10 01-FEB-10         31 0 years, 1 months.
01-JAN-10 02-FEB-10         32 0 years, 1 months.
&lt;/pre&gt;

It appears that the solution you provided, and possibly any solution using EXACT, still has issues.  For example, if you check January 5, you will see that the number of months advances when February 1 appears for the D2 column.
&lt;pre&gt;
D1        D2        DATE_DELTA T
--------- --------- ---------- ------------------
...
05-JAN-10 30-JAN-10         25 0 years, 0 months.
05-JAN-10 31-JAN-10         26 0 years, 0 months.
05-JAN-10 01-FEB-10         27 0 years, 1 months.
05-JAN-10 02-FEB-10         28 0 years, 1 months.
05-JAN-10 03-FEB-10         29 0 years, 1 months.
05-JAN-10 04-FEB-10         30 0 years, 1 months.
05-JAN-10 05-FEB-10         31 0 years, 1 months.
...
05-JAN-10 27-FEB-10         53 0 years, 1 months.
05-JAN-10 28-FEB-10         54 0 years, 1 months.
05-JAN-10 01-MAR-10         55 0 years, 2 months.
05-JAN-10 02-MAR-10         56 0 years, 2 months.
05-JAN-10 03-MAR-10         57 0 years, 2 months.
05-JAN-10 04-MAR-10         58 0 years, 2 months.
05-JAN-10 05-MAR-10         59 0 years, 2 months.
&lt;/pre&gt;

It might simply be a problem with the precision of the EXACT functionality, as mentioned in the comment by Gary.

&lt;em&gt;(Edit: In the comment I originally described how the number of months advances when January 5 is the start date (column D1) and February 1 appears in the D2 column.  Unfortunately, the code output section of the comment showed what happened when March 1 appeared in the D2 column.  I added the January 5/February 1 output to the code output section in the comment.)&lt;/em&gt;]]></description>
		<content:encoded><![CDATA[<p>Donatello,</p>
<p>That is certainly an improvement for the first day of the month:</p>
<pre>
D1        D2        DATE_DELTA T
--------- --------- ---------- ------------------
01-JAN-10 02-JAN-10          1 0 years, 0 months.
01-JAN-10 03-JAN-10          2 0 years, 0 months.
01-JAN-10 04-JAN-10          3 0 years, 0 months.
01-JAN-10 05-JAN-10          4 0 years, 0 months.
01-JAN-10 06-JAN-10          5 0 years, 0 months.
01-JAN-10 07-JAN-10          6 0 years, 0 months.
01-JAN-10 08-JAN-10          7 0 years, 0 months.
01-JAN-10 09-JAN-10          8 0 years, 0 months.
01-JAN-10 10-JAN-10          9 0 years, 0 months.
01-JAN-10 11-JAN-10         10 0 years, 0 months.
01-JAN-10 12-JAN-10         11 0 years, 0 months.
01-JAN-10 13-JAN-10         12 0 years, 0 months.
01-JAN-10 14-JAN-10         13 0 years, 0 months.
01-JAN-10 15-JAN-10         14 0 years, 0 months.
01-JAN-10 16-JAN-10         15 0 years, 0 months.
01-JAN-10 17-JAN-10         16 0 years, 0 months.
01-JAN-10 18-JAN-10         17 0 years, 0 months.
01-JAN-10 19-JAN-10         18 0 years, 0 months.
01-JAN-10 20-JAN-10         19 0 years, 0 months.
01-JAN-10 21-JAN-10         20 0 years, 0 months.
01-JAN-10 22-JAN-10         21 0 years, 0 months.
01-JAN-10 23-JAN-10         22 0 years, 0 months.
01-JAN-10 24-JAN-10         23 0 years, 0 months.
01-JAN-10 25-JAN-10         24 0 years, 0 months.
01-JAN-10 26-JAN-10         25 0 years, 0 months.
01-JAN-10 27-JAN-10         26 0 years, 0 months.
01-JAN-10 28-JAN-10         27 0 years, 0 months.
01-JAN-10 29-JAN-10         28 0 years, 0 months.
01-JAN-10 30-JAN-10         29 0 years, 0 months.
01-JAN-10 31-JAN-10         30 0 years, 0 months.
01-JAN-10 01-FEB-10         31 0 years, 1 months.
01-JAN-10 02-FEB-10         32 0 years, 1 months.
</pre>
<p>It appears that the solution you provided, and possibly any solution using EXACT, still has issues.  For example, if you check January 5, you will see that the number of months advances when February 1 appears for the D2 column.</p>
<pre>
D1        D2        DATE_DELTA T
--------- --------- ---------- ------------------
...
05-JAN-10 30-JAN-10         25 0 years, 0 months.
05-JAN-10 31-JAN-10         26 0 years, 0 months.
05-JAN-10 01-FEB-10         27 0 years, 1 months.
05-JAN-10 02-FEB-10         28 0 years, 1 months.
05-JAN-10 03-FEB-10         29 0 years, 1 months.
05-JAN-10 04-FEB-10         30 0 years, 1 months.
05-JAN-10 05-FEB-10         31 0 years, 1 months.
...
05-JAN-10 27-FEB-10         53 0 years, 1 months.
05-JAN-10 28-FEB-10         54 0 years, 1 months.
05-JAN-10 01-MAR-10         55 0 years, 2 months.
05-JAN-10 02-MAR-10         56 0 years, 2 months.
05-JAN-10 03-MAR-10         57 0 years, 2 months.
05-JAN-10 04-MAR-10         58 0 years, 2 months.
05-JAN-10 05-MAR-10         59 0 years, 2 months.
</pre>
<p>It might simply be a problem with the precision of the EXACT functionality, as mentioned in the comment by Gary.</p>
<p><em>(Edit: In the comment I originally described how the number of months advances when January 5 is the start date (column D1) and February 1 appears in the D2 column.  Unfortunately, the code output section of the comment showed what happened when March 1 appeared in the D2 column.  I added the January 5/February 1 output to the code output section in the comment.)</em></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Donatello Settembrino</title>
		<link>http://hoopercharles.wordpress.com/2010/06/02/date-delta-sql-what-is-wrong-with-this-sql-statement/#comment-1290</link>
		<dc:creator><![CDATA[Donatello Settembrino]]></dc:creator>
		<pubDate>Fri, 04 Jun 2010 10:21:12 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=2521#comment-1290</guid>
		<description><![CDATA[Hi Charles,
I think I used only twice EXTRACT, perhaps in its simplest form, honestly I don&#039;t know it very well.
curious :) , I did a test and I think that a possible solution to this problem
could be the following: 
&lt;pre&gt;
WITH DATES AS (
SELECT
  TO_DATE(&#039;01-JAN-2010&#039;,&#039;DD-MON-YYYY&#039;) + (ROWNUM-1) D
FROM
  DUAL
CONNECT BY
  LEVEL&lt;=365)
SELECT
  D1.D D1,
  D2.D D2,
  D2.D-D1.D DATE_DELTA, 
  to_char(EXTRACT(YEAR FROM D2.D) - EXTRACT(YEAR FROM  d1.d)) &#124;&#124; &#039; years, &#039; &#124;&#124;
  to_char( EXTRACT(MONTH FROM D2.D) -  EXTRACT(MONTH FROM D1.D)) &#124;&#124; &#039; months. &#039; as t 
  from
  DATES D1,
  DATES D2
WHERE
  D1.D&lt;D2.D;
&lt;/pre&gt;
but if I extract month and year in this way must also be aware that the difference between two dates is only indicative, in this example I have a difference of 71 days indicated by two months


&lt;pre&gt;
D1             D2             DATE_DELTA  T                         
-------------- -------------- ----------- ------------------
01-JAN-2010    13-MAR-2010            71  0 years, 2 months.
&lt;/pre&gt;

Regards]]></description>
		<content:encoded><![CDATA[<p>Hi Charles,<br />
I think I used only twice EXTRACT, perhaps in its simplest form, honestly I don&#8217;t know it very well.<br />
curious <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  , I did a test and I think that a possible solution to this problem<br />
could be the following: </p>
<pre>
WITH DATES AS (
SELECT
  TO_DATE('01-JAN-2010','DD-MON-YYYY') + (ROWNUM-1) D
FROM
  DUAL
CONNECT BY
  LEVEL&lt;=365)
SELECT
  D1.D D1,
  D2.D D2,
  D2.D-D1.D DATE_DELTA, 
  to_char(EXTRACT(YEAR FROM D2.D) - EXTRACT(YEAR FROM  d1.d)) || &#039; years, &#039; ||
  to_char( EXTRACT(MONTH FROM D2.D) -  EXTRACT(MONTH FROM D1.D)) || &#039; months. &#039; as t 
  from
  DATES D1,
  DATES D2
WHERE
  D1.D&lt;D2.D;
</pre>
<p>but if I extract month and year in this way must also be aware that the difference between two dates is only indicative, in this example I have a difference of 71 days indicated by two months</p>
<pre>
D1             D2             DATE_DELTA  T                         
-------------- -------------- ----------- ------------------
01-JAN-2010    13-MAR-2010            71  0 years, 2 months.
</pre>
<p>Regards</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sean Molloy</title>
		<link>http://hoopercharles.wordpress.com/2010/06/02/date-delta-sql-what-is-wrong-with-this-sql-statement/#comment-1282</link>
		<dc:creator><![CDATA[Sean Molloy]]></dc:creator>
		<pubDate>Thu, 03 Jun 2010 17:08:18 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=2521#comment-1282</guid>
		<description><![CDATA[Gray is right in his analysis.

It helps me to think of it in these terms:

For:
select extract(month from ( dt1 - dt2 ) year to month) from dual;

Oracle calculate dt1 - dt2.
Oracle converts this number of days to a &quot;interval year to month&quot; value.
A &quot;interval year to month&quot; value cannot have a fractional month, so the month value is rounded.

So we do not get the same precision as months_between.


See http://forums.oracle.com/forums/thread.jspa?threadID=354651 for more discussion.]]></description>
		<content:encoded><![CDATA[<p>Gray is right in his analysis.</p>
<p>It helps me to think of it in these terms:</p>
<p>For:<br />
select extract(month from ( dt1 &#8211; dt2 ) year to month) from dual;</p>
<p>Oracle calculate dt1 &#8211; dt2.<br />
Oracle converts this number of days to a &#8220;interval year to month&#8221; value.<br />
A &#8220;interval year to month&#8221; value cannot have a fractional month, so the month value is rounded.</p>
<p>So we do not get the same precision as months_between.</p>
<p>See <a href="http://forums.oracle.com/forums/thread.jspa?threadID=354651" rel="nofollow">http://forums.oracle.com/forums/thread.jspa?threadID=354651</a> for more discussion.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sokrates</title>
		<link>http://hoopercharles.wordpress.com/2010/06/02/date-delta-sql-what-is-wrong-with-this-sql-statement/#comment-1281</link>
		<dc:creator><![CDATA[Sokrates]]></dc:creator>
		<pubDate>Thu, 03 Jun 2010 17:07:56 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=2521#comment-1281</guid>
		<description><![CDATA[(13) year to month
is not a valid SQL Expression

((TO_DATE(&#039;03-MAR-2010&#039;,&#039;DD-MON-YYYY&#039;)-TO_DATE(&#039;18-FEB-2010&#039;,&#039;DD-MON-YYYY&#039;))) year to month
is a valid SQL Expression

see
http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/expressions009.htm#sthref1885

the difference in the brackets is **NOT** &quot;evaluated at first&quot; to a number]]></description>
		<content:encoded><![CDATA[<p>(13) year to month<br />
is not a valid SQL Expression</p>
<p>((TO_DATE(&#8217;03-MAR-2010&#8242;,&#8217;DD-MON-YYYY&#8217;)-TO_DATE(&#8217;18-FEB-2010&#8242;,&#8217;DD-MON-YYYY&#8217;))) year to month<br />
is a valid SQL Expression</p>
<p>see<br />
<a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/expressions009.htm#sthref1885" rel="nofollow">http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/expressions009.htm#sthref1885</a></p>
<p>the difference in the brackets is **NOT** &#8220;evaluated at first&#8221; to a number</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Charles Hooper</title>
		<link>http://hoopercharles.wordpress.com/2010/06/02/date-delta-sql-what-is-wrong-with-this-sql-statement/#comment-1280</link>
		<dc:creator><![CDATA[Charles Hooper]]></dc:creator>
		<pubDate>Thu, 03 Jun 2010 15:09:25 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=2521#comment-1280</guid>
		<description><![CDATA[To keep people thinking about the SQL statement at the start of this article, the documentation reference that I provided in the article for the EXTRACT function (http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/functions057.htm) includes the following SQL statement:
&lt;pre&gt;
SELECT EXTRACT(month FROM order_date) &quot;Month&quot;,
  COUNT(order_date) &quot;No. of Orders&quot;
  FROM orders
  GROUP BY EXTRACT(month FROM order_date)
  ORDER BY &quot;No. of Orders&quot; DESC;
&lt;/pre&gt;

Let&#039;s put the SQL statement to the test:
&lt;pre&gt;
CREATE TABLE T7 (ORDER_DATE DATE);
 
INSERT INTO
  T7
SELECT
  TO_DATE(&#039;01-JAN-2010&#039;,&#039;DD-MON-YYYY&#039;)+(ROWNUM-1)
FROM
  DUAL
CONNECT BY
  LEVEL&lt;=300;
 
COMMIT;
 
SELECT EXTRACT(month FROM order_date) &quot;Month&quot;,
  COUNT(order_date) &quot;No. of Orders&quot;
  FROM T7
  GROUP BY EXTRACT(month FROM order_date)
  ORDER BY &quot;No. of Orders&quot; DESC;
 
Month No. of Orders
----- -------------
    1            31
    5            31
    7            31
    3            31
    8            31
    9            30
    4            30
    6            30
    2            28
   10            27
&lt;/pre&gt;

That worked exactly as expected, but are we really seeing the 31 days that fall into January, or is Oracle rounding and stealing part of the days from February (the previous tests show that this is not the way the rounding was working - the days would actually be stolen from January and given to Feburary).  Now to verify:
&lt;pre&gt;
SELECT EXTRACT(month FROM order_date) &quot;Month&quot;,
  COUNT(order_date) &quot;No. of Orders&quot;
  FROM T7
WHERE
  ORDER_DATE BETWEEN  TO_DATE(&#039;01-JAN-2010&#039;,&#039;DD-MON-YYYY&#039;) AND  TO_DATE(&#039;31-JAN-2010&#039;,&#039;DD-MON-YYYY&#039;)
  GROUP BY EXTRACT(month FROM order_date)
  ORDER BY &quot;No. of Orders&quot; DESC;
 
Month No. of Orders
----- -------------
    1            31
&lt;/pre&gt;

That worked exactly as I thought that it should.

Now back to the original question, what is wrong with that SQL statement?  :-)]]></description>
		<content:encoded><![CDATA[<p>To keep people thinking about the SQL statement at the start of this article, the documentation reference that I provided in the article for the EXTRACT function (<a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/functions057.htm" rel="nofollow">http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/functions057.htm</a>) includes the following SQL statement:</p>
<pre>
SELECT EXTRACT(month FROM order_date) "Month",
  COUNT(order_date) "No. of Orders"
  FROM orders
  GROUP BY EXTRACT(month FROM order_date)
  ORDER BY "No. of Orders" DESC;
</pre>
<p>Let&#8217;s put the SQL statement to the test:</p>
<pre>
CREATE TABLE T7 (ORDER_DATE DATE);
 
INSERT INTO
  T7
SELECT
  TO_DATE('01-JAN-2010','DD-MON-YYYY')+(ROWNUM-1)
FROM
  DUAL
CONNECT BY
  LEVEL&lt;=300;
 
COMMIT;
 
SELECT EXTRACT(month FROM order_date) "Month",
  COUNT(order_date) "No. of Orders"
  FROM T7
  GROUP BY EXTRACT(month FROM order_date)
  ORDER BY "No. of Orders" DESC;
 
Month No. of Orders
----- -------------
    1            31
    5            31
    7            31
    3            31
    8            31
    9            30
    4            30
    6            30
    2            28
   10            27
</pre>
<p>That worked exactly as expected, but are we really seeing the 31 days that fall into January, or is Oracle rounding and stealing part of the days from February (the previous tests show that this is not the way the rounding was working &#8211; the days would actually be stolen from January and given to Feburary).  Now to verify:</p>
<pre>
SELECT EXTRACT(month FROM order_date) "Month",
  COUNT(order_date) "No. of Orders"
  FROM T7
WHERE
  ORDER_DATE BETWEEN  TO_DATE('01-JAN-2010','DD-MON-YYYY') AND  TO_DATE('31-JAN-2010','DD-MON-YYYY')
  GROUP BY EXTRACT(month FROM order_date)
  ORDER BY "No. of Orders" DESC;
 
Month No. of Orders
----- -------------
    1            31
</pre>
<p>That worked exactly as I thought that it should.</p>
<p>Now back to the original question, what is wrong with that SQL statement?  <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Charles Hooper</title>
		<link>http://hoopercharles.wordpress.com/2010/06/02/date-delta-sql-what-is-wrong-with-this-sql-statement/#comment-1278</link>
		<dc:creator><![CDATA[Charles Hooper]]></dc:creator>
		<pubDate>Thu, 03 Jun 2010 11:11:59 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=2521#comment-1278</guid>
		<description><![CDATA[The first documentation reference that you provided is the exact reason why I initially marked this SQL statement as being wrong.  Assume that subtracting the second date from the first date results in the numeric value of 13 (just to keep things simple).  The first question is &quot;What is the assumed year?&quot; - is it this year (2010), 2008, 1970, 1900, 1902, etc.  The second question is &quot;What is the assumed month&quot; - is it January, February, March, etc.  The third question is &quot;What is the assumed day of the month for the zero point starting date?&quot; - is it today&#039;s day of the month, the first day of the current month, the first day of January, etc.  What if the starting date and ending date span multiple years (the birth date and death date of someone famous, for example)?

Back to the example of the numeric value 13.  Something odd is going on with this EXTRACT function.  In this case, the result of subtracting a date from a date is not a number:
&lt;pre&gt;
SELECT
  extract(year from (13) year to month) &#124;&#124; &#039; years, &#039; &#124;&#124;
  extract(month from (13) year to month) &#124;&#124; &#039; months. &#039; T
FROM
  DUAL;
  
ERROR at line 2:
ORA-30083: syntax error was found in interval value expression
  
SELECT
  (TO_DATE(&#039;03-MAR-2010&#039;,&#039;DD-MON-YYYY&#039;)-TO_DATE(&#039;18-FEB-2010&#039;,&#039;DD-MON-YYYY&#039;)) DAYS,
  extract(year from ((TO_DATE(&#039;03-MAR-2010&#039;,&#039;DD-MON-YYYY&#039;)-TO_DATE(&#039;18-FEB-2010&#039;,&#039;DD-MON-YYYY&#039;))) year to month) &#124;&#124; &#039; years, &#039; &#124;&#124;
  extract(month from ((TO_DATE(&#039;03-MAR-2010&#039;,&#039;DD-MON-YYYY&#039;)-TO_DATE(&#039;18-FEB-2010&#039;,&#039;DD-MON-YYYY&#039;))) year to month) &#124;&#124; &#039; months. &#039; T
FROM
  DUAL;
 
      DAYS T
---------- --------------------
        13 0 years, 1 months.
 
SELECT
  (TO_DATE(&#039;02-MAR-2008&#039;,&#039;DD-MON-YYYY&#039;)-TO_DATE(&#039;18-FEB-2008&#039;,&#039;DD-MON-YYYY&#039;)) DAYS,
  extract(year from ((TO_DATE(&#039;02-MAR-2008&#039;,&#039;DD-MON-YYYY&#039;)-TO_DATE(&#039;18-FEB-2008&#039;,&#039;DD-MON-YYYY&#039;))) year to month) &#124;&#124; &#039; years, &#039; &#124;&#124;
  extract(month from ((TO_DATE(&#039;02-MAR-2008&#039;,&#039;DD-MON-YYYY&#039;)-TO_DATE(&#039;18-FEB-2008&#039;,&#039;DD-MON-YYYY&#039;))) year to month) &#124;&#124; &#039; months. &#039; T
FROM
  DUAL;
 
      DAYS T
---------- --------------------
        13 0 years, 0 months.
&lt;/pre&gt;

The number 13 causes the SQL statement to fail.  In the second of the above SQL statements, if Oracle assumed that 13 was in January of any year, months should evaluate to 0, but Oracle returned a value of 1 month.  In the third of the above SQL statements, if Oracle assumed that 13 was in February of this year, like the second example, then Oracle should have returned a value of 0 months.

Another interesting result was provided in the code section of my previous response.  It appears that Oracle is not strictly rounding the results of &quot;extract(month from (D2.D-D1.D) year to month)&quot; using the same calculation as used by the MONTHS_BETWEEN function.  If that was the case, the date range of 01-JAN-2010 through 16-JAN-2010 would be rounded down to 0 months, but 16-JAN-2010 is indicated as the start of 1 month:
&lt;pre&gt;
D1        D2        DATE_DELTA T                      MONTHS   M   D
--------- --------- ---------- -------------------- -------- --- ---
01-JAN-10 15-JAN-10         14 0 years, 0 months.     0.4516   0  14
01-JAN-10 16-JAN-10         15 0 years, 1 months.     0.4839   0  15
01-JAN-10 17-JAN-10         16 0 years, 1 months.     0.5161   0  16
&lt;/pre&gt;

I probably need to spend some more time working with the EXTRACT function.]]></description>
		<content:encoded><![CDATA[<p>The first documentation reference that you provided is the exact reason why I initially marked this SQL statement as being wrong.  Assume that subtracting the second date from the first date results in the numeric value of 13 (just to keep things simple).  The first question is &#8220;What is the assumed year?&#8221; &#8211; is it this year (2010), 2008, 1970, 1900, 1902, etc.  The second question is &#8220;What is the assumed month&#8221; &#8211; is it January, February, March, etc.  The third question is &#8220;What is the assumed day of the month for the zero point starting date?&#8221; &#8211; is it today&#8217;s day of the month, the first day of the current month, the first day of January, etc.  What if the starting date and ending date span multiple years (the birth date and death date of someone famous, for example)?</p>
<p>Back to the example of the numeric value 13.  Something odd is going on with this EXTRACT function.  In this case, the result of subtracting a date from a date is not a number:</p>
<pre>
SELECT
  extract(year from (13) year to month) || ' years, ' ||
  extract(month from (13) year to month) || ' months. ' T
FROM
  DUAL;
  
ERROR at line 2:
ORA-30083: syntax error was found in interval value expression
  
SELECT
  (TO_DATE('03-MAR-2010','DD-MON-YYYY')-TO_DATE('18-FEB-2010','DD-MON-YYYY')) DAYS,
  extract(year from ((TO_DATE('03-MAR-2010','DD-MON-YYYY')-TO_DATE('18-FEB-2010','DD-MON-YYYY'))) year to month) || ' years, ' ||
  extract(month from ((TO_DATE('03-MAR-2010','DD-MON-YYYY')-TO_DATE('18-FEB-2010','DD-MON-YYYY'))) year to month) || ' months. ' T
FROM
  DUAL;
 
      DAYS T
---------- --------------------
        13 0 years, 1 months.
 
SELECT
  (TO_DATE('02-MAR-2008','DD-MON-YYYY')-TO_DATE('18-FEB-2008','DD-MON-YYYY')) DAYS,
  extract(year from ((TO_DATE('02-MAR-2008','DD-MON-YYYY')-TO_DATE('18-FEB-2008','DD-MON-YYYY'))) year to month) || ' years, ' ||
  extract(month from ((TO_DATE('02-MAR-2008','DD-MON-YYYY')-TO_DATE('18-FEB-2008','DD-MON-YYYY'))) year to month) || ' months. ' T
FROM
  DUAL;
 
      DAYS T
---------- --------------------
        13 0 years, 0 months.
</pre>
<p>The number 13 causes the SQL statement to fail.  In the second of the above SQL statements, if Oracle assumed that 13 was in January of any year, months should evaluate to 0, but Oracle returned a value of 1 month.  In the third of the above SQL statements, if Oracle assumed that 13 was in February of this year, like the second example, then Oracle should have returned a value of 0 months.</p>
<p>Another interesting result was provided in the code section of my previous response.  It appears that Oracle is not strictly rounding the results of &#8220;extract(month from (D2.D-D1.D) year to month)&#8221; using the same calculation as used by the MONTHS_BETWEEN function.  If that was the case, the date range of 01-JAN-2010 through 16-JAN-2010 would be rounded down to 0 months, but 16-JAN-2010 is indicated as the start of 1 month:</p>
<pre>
D1        D2        DATE_DELTA T                      MONTHS   M   D
--------- --------- ---------- -------------------- -------- --- ---
01-JAN-10 15-JAN-10         14 0 years, 0 months.     0.4516   0  14
01-JAN-10 16-JAN-10         15 0 years, 1 months.     0.4839   0  15
01-JAN-10 17-JAN-10         16 0 years, 1 months.     0.5161   0  16
</pre>
<p>I probably need to spend some more time working with the EXTRACT function.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sokrates</title>
		<link>http://hoopercharles.wordpress.com/2010/06/02/date-delta-sql-what-is-wrong-with-this-sql-statement/#comment-1277</link>
		<dc:creator><![CDATA[Sokrates]]></dc:creator>
		<pubDate>Thu, 03 Jun 2010 07:20:07 +0000</pubDate>
		<guid isPermaLink="false">http://hoopercharles.wordpress.com/?p=2521#comment-1277</guid>
		<description><![CDATA[this syntax was new for me and I agree with you, that it is &quot;incorrect&quot; or &quot;unexpected&quot;
However, I&#039;m still not sure how to fix it]]></description>
		<content:encoded><![CDATA[<p>this syntax was new for me and I agree with you, that it is &#8220;incorrect&#8221; or &#8220;unexpected&#8221;<br />
However, I&#8217;m still not sure how to fix it</p>
]]></content:encoded>
	</item>
</channel>
</rss>
