<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Eddie Awad&#039;s Blog &#187; Joins</title>
	<atom:link href="http://awads.net/wp/category/oracle/joins/feed/" rel="self" type="application/rss+xml" />
	<link>http://awads.net/wp</link>
	<description>News, views, tips and tricks on Oracle and other fun stuff</description>
	<lastBuildDate>Tue, 31 Jan 2012 13:00:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<atom:link rel='hub' href='http://awads.net/wp/?pushpress=hub'/>
		<item>
		<title>Did You Know This About Outer Joins in Oracle?</title>
		<link>http://awads.net/wp/2007/12/11/did-you-know-this-about-outer-joins-in-oracle/</link>
		<comments>http://awads.net/wp/2007/12/11/did-you-know-this-about-outer-joins-in-oracle/#comments</comments>
		<pubDate>Wed, 12 Dec 2007 07:04:05 +0000</pubDate>
		<dc:creator>Eddie Awad</dc:creator>
				<category><![CDATA[Joins]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[join]]></category>

		<guid isPermaLink="false">http://awads.net/wp/2007/12/11/did-you-know-this-about-outer-joins-in-oracle/</guid>
		<description><![CDATA[Here is something interesting. Oracle converts this outer join query SELECT T1.d, T2.c FROM T1, T2 WHERE T1.x = T2.x (+) and T2.y &#62; 5; and its ANSI equivalent SELECT T1.d, T2.c FROM T1 LEFT OUTER JOIN T2 ON (T1.x = T2.x) WHERE T2.y &#62; 5; into this inner join query SELECT T1.d, T2.c FROM [...]]]></description>
			<content:encoded><![CDATA[<p>Here is something interesting. Oracle converts this outer join query</p>

<pre><code>SELECT T1.d, T2.c
FROM T1, T2
WHERE T1.x = T2.x (+) and T2.y &gt; 5;
</code></pre>

<p>and its ANSI equivalent</p>

<pre><code>SELECT T1.d, T2.c
FROM T1 LEFT OUTER JOIN T2
ON (T1.x = T2.x)
WHERE T2.y &gt; 5;
</code></pre>

<p>into this inner join query</p>

<pre><code>SELECT T1.d, T2.c
FROM T1, T2
WHERE T1.x = T2.x and T2.y &gt; 5;
</code></pre>

<p>That&#8217;s according to the <a href="http://optimizermagic.blogspot.com/">Optimizer Development Group blog</a>. They go on to explain:</p>

<blockquote>
  <p>Here the filter predicate on the outer-joined table T2 does not contain the outerjoin operator (+); thus it will be applied after the left outerjoin has taken place. This will result in the elimination of all null appended rows of T2. Hence, Oracle converts the outer join into an inner join.</p>
</blockquote>

<p>And here is an interesting thing about ANSI full outer joins:</p>

<blockquote>
  <p>Before Oracle 11gR1 all ANSI full outerjoins were converted into a UNION ALL query with two branches, where one branch contained a left outerjoined lateral view and the other branch contained a NOT EXISTS subquery. A native support for hash full outerjoin was introduced in 11gR1 to overcome this problem. When the native full outerjoin cannot be used, Oracle reverts to the pre-11gR1 strategy.</p>
</blockquote>

<p>Their latest blog post about <a href="http://optimizermagic.blogspot.com/2007/12/outerjoins-in-oracle.html">Outerjoins in Oracle</a> is a good read.</p>
<p>Related articles:<ul>
<li><a href='http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/' rel='bookmark' title='Back to basics: outer joins'>Back to basics: outer joins</a></li>
<li><a href='http://awads.net/wp/2005/07/01/outer-joins-and-or/' rel='bookmark' title='Outer joins and &#8220;OR&#8221;'>Outer joins and &#8220;OR&#8221;</a></li>
<li><a href='http://awads.net/wp/2006/07/11/back-to-basics-self-joins/' rel='bookmark' title='Back to basics: self joins'>Back to basics: self joins</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://awads.net/wp/2007/12/11/did-you-know-this-about-outer-joins-in-oracle/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
	</item>
		<item>
		<title>SQL Joins as Seen on a Diagram</title>
		<link>http://awads.net/wp/2007/10/12/sql-joins-as-seen-on-a-diagram/</link>
		<comments>http://awads.net/wp/2007/10/12/sql-joins-as-seen-on-a-diagram/#comments</comments>
		<pubDate>Fri, 12 Oct 2007 19:30:30 +0000</pubDate>
		<dc:creator>Eddie Awad</dc:creator>
				<category><![CDATA[Joins]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[join]]></category>

		<guid isPermaLink="false">http://awads.net/wp/2007/10/12/sql-joins-as-seen-on-a-diagram/</guid>
		<description><![CDATA[Jeff Atwood, the author of the Coding Horror blog, has a nice visual explanation of SQL joins. For the non-visual explanation, I refer you to the following articles: Inner joins Outer joins Cross joins Self joins Equi and non-equijoins Anti-joins and semi-joins However, ANSI SQL join syntax does not always work in Oracle, at least [...]]]></description>
			<content:encoded><![CDATA[<p>Jeff Atwood, the author of the <a href="http://www.codinghorror.com/blog/">Coding Horror</a> blog, has a nice <a href="http://www.codinghorror.com/blog/archives/000976.html">visual explanation of SQL joins</a>. For the non-visual explanation, I refer you to the following articles:</p>

<ul>
<li><a href="http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/">Inner joins</a></li>
<li><a href="http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/">Outer joins</a></li>
<li><a href="http://awads.net/wp/2006/03/16/back-to-basics-cross-joins/">Cross joins</a></li>
<li><a href="http://awads.net/wp/2006/07/11/back-to-basics-self-joins/">Self joins</a></li>
<li><a href="http://awads.net/wp/2006/04/26/back-to-basics-equi-and-non-equijoins/">Equi and non-equijoins</a></li>
<li><a href="http://awads.net/wp/2007/05/01/back-to-basics-anti-joins-and-semi-joins/">Anti-joins and semi-joins</a></li>
</ul>

<p>However, <a href="http://awads.net/wp/2007/06/14/when-ansi-sql-join-syntax-does-not-work-in-oracle/">ANSI SQL join syntax does not always work in Oracle</a>, at least up to version 10gR2.</p>
<p>Related articles:<ul>
<li><a href='http://awads.net/wp/2006/03/16/back-to-basics-cross-joins/' rel='bookmark' title='Back to basics: cross joins'>Back to basics: cross joins</a></li>
<li><a href='http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/' rel='bookmark' title='Back to basics: outer joins'>Back to basics: outer joins</a></li>
<li><a href='http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/' rel='bookmark' title='Back to basics: inner joins'>Back to basics: inner joins</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://awads.net/wp/2007/10/12/sql-joins-as-seen-on-a-diagram/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
	</item>
		<item>
		<title>When ANSI SQL Join Syntax Does Not Work in Oracle</title>
		<link>http://awads.net/wp/2007/06/14/when-ansi-sql-join-syntax-does-not-work-in-oracle/</link>
		<comments>http://awads.net/wp/2007/06/14/when-ansi-sql-join-syntax-does-not-work-in-oracle/#comments</comments>
		<pubDate>Fri, 15 Jun 2007 00:32:24 +0000</pubDate>
		<dc:creator>Eddie Awad</dc:creator>
				<category><![CDATA[Joins]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[join]]></category>

		<guid isPermaLink="false">http://awads.net/wp/2007/06/14/when-ansi-sql-join-syntax-does-not-work-in-oracle/</guid>
		<description><![CDATA[I have lost confidence in Oracle&#8217;s ANSI style SQL. Eric, in his comment to the post Back to basics: anti-joins and semi-joins, warned me of the following gotcha: If you are writing queries that select from many tables, like denormalizing data for warehousing, and the sum of the columns in those tables exceeds 1,050, you [...]]]></description>
			<content:encoded><![CDATA[<p>I have lost confidence in Oracle&#8217;s ANSI style SQL. Eric, in <a href="http://awads.net/wp/2007/05/01/back-to-basics-anti-joins-and-semi-joins/#comment-50734">his comment</a> to the post <a href="http://awads.net/wp/2007/05/01/back-to-basics-anti-joins-and-semi-joins/">Back to basics: anti-joins and semi-joins</a>, warned me of the following gotcha:</p>

<blockquote>
  <p>If you are writing queries that select from many tables, like denormalizing data for warehousing, and the sum of the columns in those tables exceeds 1,050, you always get ORA-01445. This occurs from 9i through 10g2, and has happened often enough to me that I avoid my preference for ANSI syntax on Oracle databases, unless I&#8217;m just selecting from a few tables.</p>
</blockquote>

<p>Well, it just happened to me. Below are two queries. They both select from standard Oracle E-Business Suite (11.5.10) tables. The two queries are identical except that the first uses the ANSI style syntax, and the second uses the Oracle syntax. As you can see below, the query that uses ANSI joins failed miserably with the error:</p>

<p><em>ORA-01445: cannot select ROWID from, or sample, a join view without a key-preserved table</em>.</p>

<p>This looks like a bug to me. Interestingly, if you change the SELECT NULL to SELECT COUNT(*), the query executes successfully. <span id="more-565"></span></p>

<pre><code>APPS@sigma&gt; select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.1.0.5.0 - Prod
PL/SQL Release 10.1.0.5.0 - Production
CORE    10.1.0.5.0      Production
TNS for Linux: Version 10.1.0.5.0 - Production
NLSRTL Version 10.1.0.5.0 - Production

APPS@sigma&gt; SELECT NULL
  2    FROM oe_order_headers_all header INNER JOIN oe_order_lines_all line
  3         ON header.header_id = line.header_id
  4         INNER JOIN ra_customers cust ON header.sold_to_org_id = cust.customer_id
  5         INNER JOIN mtl_system_items_b item
  6         ON item.inventory_item_id = line.inventory_item_id
  7       AND item.organization_id = line.ship_from_org_id
  8         INNER JOIN org_organization_definitions org
  9         ON org.organization_id = line.ship_from_org_id
 10         LEFT OUTER JOIN ra_salesreps_all salesrep
 11         ON salesrep.salesrep_id = header.salesrep_id
 12       AND salesrep.org_id = header.org_id
 13         LEFT OUTER JOIN hr_locations_all sales_loc
 14         ON sales_loc.location_id = salesrep.attribute1
 15   WHERE header.orig_sys_document_ref = 'OE_ORDER_HEADERS_ALL74846'
 16     AND header.order_source_id = 0;

       LEFT OUTER JOIN hr_locations_all sales_loc
                       *
ERROR at line 13:
ORA-01445: cannot select ROWID from, or sample, a join view without a
key-preserved table
</code></pre>

<p>Now, using the good old Oracle SQL syntax:</p>

<pre><code>APPS@sigma&gt; SELECT NULL
  2    FROM oe_order_headers_all header,
  3         oe_order_lines_all line,
  4         ra_customers cust,
  5         mtl_system_items_b item,
  6         org_organization_definitions org,
  7         ra_salesreps_all salesrep,
  8         hr_locations_all sales_loc
  9   WHERE header.header_id = line.header_id
 10     AND header.sold_to_org_id = cust.customer_id
 11     AND item.inventory_item_id = line.inventory_item_id
 12     AND item.organization_id = line.ship_from_org_id
 13     AND org.organization_id = line.ship_from_org_id
 14     AND salesrep.salesrep_id(+) = header.salesrep_id
 15     AND salesrep.org_id(+) = header.org_id
 16     AND sales_loc.location_id(+) = salesrep.attribute1
 17     AND header.orig_sys_document_ref = 'OE_ORDER_HEADERS_ALL74846'
 18     AND header.order_source_id = 0;

N
-


2 rows selected.
</code></pre>

<p>Another interesting observation is that I could not find any reference to the ORA-01445 error in the Oracle Database Error Messages document for versions <a href="http://download-west.oracle.com/docs/cd/B14117_01/server.101/b10744/e900.htm#sthref30">10.1</a> and <a href="http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14219/e900.htm#sthref409">10.2</a>. I did however find the following references:</p>

<ul>
<li><a href="http://www.halfcooked.com/mt/archives/000936.html">Andrew Channels Dexter Pinion: ORA-01445</a></li>
<li><a href="http://www.freelists.org/archives/oracle-l/04-2005/msg01235.html">Oracle-l: limit on number of tables in join</a></li>
<li><a href="http://www.orafaq.com/forum/?t=msg&amp;th=11983/0/">OraFAQ Forum: Urgent-ORA-01445</a></li>
<li><a href="http://www.webservertalk.com/archive149-2005-8-1171381.html">Outer join &#8211; same query, different results</a></li>
<li><a href="https://metalink.oracle.com/metalink/plsql/f?p=130:15:1791121095335348748::::p15_database_id,p15_docid,p15_show_header,p15_show_help,p15_black_frame,p15_font:BUG,5967612,1,1,1,helvetica">Oracle bug no. 5967612 on Metalink</a></li>
</ul>
<p>Related articles:<ul>
<li><a href='http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/' rel='bookmark' title='Back to basics: inner joins'>Back to basics: inner joins</a></li>
<li><a href='http://awads.net/wp/2007/05/01/back-to-basics-anti-joins-and-semi-joins/' rel='bookmark' title='Back to basics: anti-joins and semi-joins'>Back to basics: anti-joins and semi-joins</a></li>
<li><a href='http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/' rel='bookmark' title='Back to basics: outer joins'>Back to basics: outer joins</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://awads.net/wp/2007/06/14/when-ansi-sql-join-syntax-does-not-work-in-oracle/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
	
	</item>
		<item>
		<title>Back to basics: anti-joins and semi-joins</title>
		<link>http://awads.net/wp/2007/05/01/back-to-basics-anti-joins-and-semi-joins/</link>
		<comments>http://awads.net/wp/2007/05/01/back-to-basics-anti-joins-and-semi-joins/#comments</comments>
		<pubDate>Wed, 02 May 2007 05:47:13 +0000</pubDate>
		<dc:creator>Eddie Awad</dc:creator>
				<category><![CDATA[Joins]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[join]]></category>

		<guid isPermaLink="false">http://awads.net/wp/2007/05/01/back-to-basics-anti-joins-and-semi-joins/</guid>
		<description><![CDATA[I almost forgot that the Oracle Joins series is not complete yet. So here is the last episode, a quick and easy anti-join and semi-join refresher. Anti-joins: Anti-joins are written using the NOT EXISTS or NOT IN constructs. An anti-join between two tables returns rows from the first table for which there are no corresponding [...]]]></description>
			<content:encoded><![CDATA[<p>I almost forgot that the <a href="http://awads.net/wp/2006/03/16/back-to-basics-cross-joins/">Oracle Joins series</a> is not complete yet. So here is the last episode, a quick and easy anti-join and semi-join refresher.</p>

<p><strong>Anti-joins</strong>:<br />
Anti-joins are written using the NOT EXISTS or NOT IN constructs. An anti-join between two tables returns rows from the first table for which there are no corresponding rows in the second table. In other words, it returns rows that fail to match the sub-query on the right side.</p>

<p>Suppose you want a list of departments with no employees. You could write a query like this:</p>

<pre><code>SELECT   d.department_name
    FROM departments d
MINUS
SELECT   d.department_name
    FROM departments d, employees e
   WHERE d.department_id = e.department_id
ORDER BY department_name;
</code></pre>

<p>The above query will give the desired results, but it might be clearer to write the query using an anti-join:</p>

<pre><code>SELECT   d.department_name
    FROM departments d
   WHERE NOT EXISTS (SELECT NULL
                       FROM employees e
                      WHERE e.department_id = d.department_id)
ORDER BY d.department_name;
</code></pre>

<p><strong>Semi-joins</strong>:<br />
Semi-joins are written using the EXISTS or IN constructs. A semi-join between two tables returns rows from the first table where one or more matches are found in the second table. The difference between a semi-join and a conventional join is that rows in the first table will be returned at most once.</p>

<p>Suppose you want a list of departments with at least one employee. You could write the query like this:</p>

<pre><code>SELECT   d.department_name
    FROM departments d, employees e
   WHERE d.department_id = e.department_id
ORDER BY department_name;
</code></pre>

<p>The department name in the query result will appear as many times as the number of employees in it. So, for example if a department has 30 employees then that department will appear in the query output 30 times.</p>

<p>To eliminate the duplicate rows, you could use the DISTINCT or GROUP BY keywords. A more elegant solution is to use a semi-join between the departments and employees tables instead of a conventional join:</p>

<pre><code>SELECT   d.department_name
    FROM departments d
   WHERE EXISTS (SELECT NULL
                   FROM employees e
                  WHERE e.department_id = d.department_id)
ORDER BY d.department_name;
</code></pre>

<p>The above query will list the departments that have at least one employee. The department will appear only once in the query output no matter how many employees it has.</p>

<p><strong>Sources and Resources</strong>:</p>

<ul>
<li><a href="http://www.dbspecialists.com/presentations/semijoins.html">Speeding Up Queries with Semi-Joins and Anti-Joins</a></li>
<li><a href="http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14200/queries006.htm#sthref3182">Documentation</a></li>
</ul>
<p>Related articles:<ul>
<li><a href='http://awads.net/wp/2006/03/16/back-to-basics-cross-joins/' rel='bookmark' title='Back to basics: cross joins'>Back to basics: cross joins</a></li>
<li><a href='http://awads.net/wp/2006/07/11/back-to-basics-self-joins/' rel='bookmark' title='Back to basics: self joins'>Back to basics: self joins</a></li>
<li><a href='http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/' rel='bookmark' title='Back to basics: outer joins'>Back to basics: outer joins</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://awads.net/wp/2007/05/01/back-to-basics-anti-joins-and-semi-joins/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
	</item>
		<item>
		<title>Give Me One Minute And I&#8217;ll Tell You If You Are Liberal Or Conservative</title>
		<link>http://awads.net/wp/2006/11/05/give-me-one-minute-and-ill-tell-you-if-you-are-liberal-or-conservative/</link>
		<comments>http://awads.net/wp/2006/11/05/give-me-one-minute-and-ill-tell-you-if-you-are-liberal-or-conservative/#comments</comments>
		<pubDate>Mon, 06 Nov 2006 00:20:34 +0000</pubDate>
		<dc:creator>Eddie Awad</dc:creator>
				<category><![CDATA[Interesting Stuff]]></category>
		<category><![CDATA[Joins]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[election]]></category>
		<category><![CDATA[politics]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://awads.net/wp/2006/11/05/give-me-one-minute-and-ill-tell-you-if-you-are-liberal-or-conservative/</guid>
		<description><![CDATA[This Tuesday is election day in the United States. It&#8217;s a big day. Political enthusiasts from both the Republican and Democrat parties go to the polls and vote for their preferred candidates for member of Congress, state legislature and governor. But, what does this have to do with databases. Well, it turns out that the [...]]]></description>
			<content:encoded><![CDATA[<p>This Tuesday is <a href="http://en.wikipedia.org/wiki/United_States_general_elections%2C_2006">election day</a> in the United States. It&#8217;s a big day. Political enthusiasts from both the Republican and Democrat parties go to the polls and vote for their preferred candidates for member of Congress, state legislature and governor.</p>

<p>But, what does this have to do with databases. Well, it <a href="http://www.hashemian.com/blog/2006/11/politics-of-sql-left-join-and-right.htm">turns out</a> that the SQL language has politics embedded in it. For example, consider the following two simple queries:</p>

<p>Query 1:</p>

<pre><code>SELECT emp.last_name,
       dept.department_name
  FROM departments dept LEFT OUTER JOIN employees emp
       ON dept.department_id = emp.department_id
</code></pre>

<p>Query 2:</p>

<pre><code>SELECT emp.last_name,
       dept.department_name
  FROM employees emp RIGHT OUTER JOIN departments dept
       ON dept.department_id = emp.department_id
</code></pre>

<p>Both queries return the same result set. The difference between the two is that one uses &#8220;LEFT&#8221; and the other uses &#8220;RIGHT&#8221;.</p>

<p>Which one do you prefer using? In other words, which type of <a href="http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/">outer join</a> do you usually use in your queries, the left or the right?</p>

<p>Now, if you select query 1, the one that uses the &#8220;LEFT&#8221; join, you most probably lean towards <a href="http://en.wikipedia.org/wiki/Left-wing_politics">the left</a>. You are a liberal. As a result, you are more likely to vote Democrat this Tuesday.</p>

<p>But, if you select query 2, the one that uses the &#8220;RIGHT&#8221; join, you most probably lean towards <a href="http://en.wikipedia.org/wiki/Right-wing_politics">the right</a>. You are a conservative. As a result, you are more likely to vote Republican this Tuesday.</p>

<p>There you go. A simple test, for all of you SQL developers out there, to know your political affiliation. <img src='http://awads.net/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<p><a href="http://www.hashemian.com/blog/2006/11/politics-of-sql-left-join-and-right.htm">Some</a> have called for a boycott of all right joins and only use left joins on Tuesday. <a href="http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/#comment-4199">Others</a> have called for the abolition of both the left and the right.</p>

<p>Personally, I do not use right joins. But again, I cannot vote because I&#8217;m not a US citizen.</p>
<p>Related articles:<ul>
<li><a href='http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/' rel='bookmark' title='Back to basics: outer joins'>Back to basics: outer joins</a></li>
<li><a href='http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/' rel='bookmark' title='Back to basics: inner joins'>Back to basics: inner joins</a></li>
<li><a href='http://awads.net/wp/2005/07/01/outer-joins-and-or/' rel='bookmark' title='Outer joins and &#8220;OR&#8221;'>Outer joins and &#8220;OR&#8221;</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://awads.net/wp/2006/11/05/give-me-one-minute-and-ill-tell-you-if-you-are-liberal-or-conservative/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
	</item>
		<item>
		<title>Back to basics: self joins</title>
		<link>http://awads.net/wp/2006/07/11/back-to-basics-self-joins/</link>
		<comments>http://awads.net/wp/2006/07/11/back-to-basics-self-joins/#comments</comments>
		<pubDate>Tue, 11 Jul 2006 14:26:51 +0000</pubDate>
		<dc:creator>Eddie Awad</dc:creator>
				<category><![CDATA[Joins]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[join]]></category>

		<guid isPermaLink="false">http://awads.net/wp/2006/07/11/back-to-basics-self-joins/</guid>
		<description><![CDATA[A self join is a join of a table to itself. This table appears twice (or more) in the FROM clause and is followed by table aliases that qualify column names in the join condition and the SELECT clause. Take for example the employees table, the manager of one employee is also an employee. The [...]]]></description>
			<content:encoded><![CDATA[<p>A self join is a join of a table to itself. This table appears twice (or more) in the FROM clause and is followed by table aliases that qualify column names in the join condition and the SELECT clause. Take for example the <code>employees</code> table, the manager of one employee is also an employee. The rows for both are in the same <code>employees</code> table.</p>

<p>To get information about an employee and her manager, you have to join the employee table to itself, thereby treating <code>employees</code> as if it were two separate tables. The following example query uses a self join to return the name of each employee along with the name of the employee&#8217;s manager: <span id="more-325"></span></p>

<pre><code>SELECT e.last_name employee, m.last_name manager
  FROM employees e INNER JOIN employees m
       ON e.manager_id = m.employee_id;


         EMPLOYEE                  MANAGER          
------------------------- ------------------------- 
Kochhar                   King                      
De Haan                   King                      
Hunold                    De Haan                   
Ernst                     Hunold                    
Austin                    Hunold                    
Pataballa                 Hunold                    

...                   

106 row(s) retrieved
</code></pre>

<p>But</p>

<pre><code>SELECT COUNT (*)
  FROM employees;

               COUNT(*)                
-------------------------------------- 
                                   107 
</code></pre>

<p>Even though the <code>employees</code> table has 107 rows, the previous query returned only 106 rows. This is because there is an employee without a manager_id. Oracle excludes that employee&#8217;s row from the result set while performing the self <a href="http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/">inner join</a>. To include that employee without a manager, you need an <a href="http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/">outer join</a>:</p>

<pre><code>SELECT e.last_name employee, m.last_name manager
  FROM employees e LEFT OUTER JOIN employees m
       ON e.manager_id = m.employee_id;


         EMPLOYEE                  MANAGER          
------------------------- ------------------------- 
King                     
Kochhar                   King                      
De Haan                   King                      
Hunold                    De Haan                   
Ernst                     Hunold                    
Austin                    Hunold                    
Pataballa                 Hunold                    

...                   

107 row(s) retrieved
</code></pre>

<p>The previous examples showed self <a href="http://awads.net/wp/2006/04/26/back-to-basics-equi-and-non-equijoins/">equijoins</a>. However, there are situations when you need to perform self <a href="http://awads.net/wp/2006/04/26/back-to-basics-equi-and-non-equijoins/">non-equijoins</a>. For example, let&#8217;s assume that you are in charge of organizing an interdepartmental soccer competition for the following departments:</p>

<pre><code>SELECT department_name
  FROM departments
 WHERE department_id IN (10, 20, 30, 40);

        DEPARTMENT_NAME        
------------------------------ 
Administration                 
Marketing                      
Purchasing                     
Human Resources                

4 row(s) retrieved
</code></pre>

<p>You decide that each department plays against the other three departments <em>only once</em>, which means that the output of the query you are going to write cannot contain one combination <em>Administration, Marketing</em> and another <em>Marketing, Administration</em> because that means that each department plays against the others twice. The solution is to use a self non-equijoin query like this:</p>

<pre><code>SELECT d1.department_name dept1, d2.department_name dept2
  FROM departments d1 INNER JOIN departments d2
       ON d1.department_id &lt; d2.department_id
 WHERE d1.department_id IN (10, 20, 30, 40)
   AND d2.department_id IN (10, 20, 30, 40);

             DEPT1                          DEPT2             
------------------------------ ------------------------------ 
Administration                 Marketing                      
Administration                 Purchasing                     
Administration                 Human Resources                
Marketing                      Purchasing                     
Marketing                      Human Resources                
Purchasing                     Human Resources                

6 row(s) retrieved
</code></pre>

<p>That&#8217;s it for self joins <img src='http://awads.net/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<p>Sources:</p>

<ul>
<li><a href="http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14200/queries006.htm#i2054012">Oracle Documentation</a></li>
<li><a href="http://www.amazon.com/gp/product/0596006322/sr=8-1/qid=1152498374/ref=sr_1_1/002-6768139-9516020?ie=UTF8">Mastering Oracle SQL</a></li>
</ul>
<p>Related articles:<ul>
<li><a href='http://awads.net/wp/2007/05/01/back-to-basics-anti-joins-and-semi-joins/' rel='bookmark' title='Back to basics: anti-joins and semi-joins'>Back to basics: anti-joins and semi-joins</a></li>
<li><a href='http://awads.net/wp/2006/03/16/back-to-basics-cross-joins/' rel='bookmark' title='Back to basics: cross joins'>Back to basics: cross joins</a></li>
<li><a href='http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/' rel='bookmark' title='Back to basics: outer joins'>Back to basics: outer joins</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://awads.net/wp/2006/07/11/back-to-basics-self-joins/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
	</item>
		<item>
		<title>Back to basics: Equi and non-equijoins</title>
		<link>http://awads.net/wp/2006/04/26/back-to-basics-equi-and-non-equijoins/</link>
		<comments>http://awads.net/wp/2006/04/26/back-to-basics-equi-and-non-equijoins/#comments</comments>
		<pubDate>Wed, 26 Apr 2006 14:23:26 +0000</pubDate>
		<dc:creator>Eddie Awad</dc:creator>
				<category><![CDATA[Joins]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[join]]></category>

		<guid isPermaLink="false">http://awads.net/wp/2006/04/26/back-to-basics-equi-and-non-equijoins/</guid>
		<description><![CDATA[The join condition determines whether a join is an equijoin or a non-equijoin. An equijoin is a join with a join condition containing an equality operator. An equijoin combines rows that have equivalent values for the specified columns. When a join condition relates two tables by an operator other than equality, it is a non-equijoin. [...]]]></description>
			<content:encoded><![CDATA[<p>The join condition determines whether a join is an equijoin or a non-equijoin. An equijoin is a join with a join condition containing an equality operator. An equijoin combines rows that have equivalent values for the specified columns. When a join condition relates two tables by an operator other than equality, it is a non-equijoin. A query may contain equijoins as well as non-equijoins.</p>

<p>Equijoins are the most commonly used. An example of an equijoin: <span id="more-267"></span></p>

<pre>
SELECT e.first_name, d.department_name
  FROM employees e INNER JOIN departments d
       ON e.department_id = d.department_id
/
       
     FIRST_NAME              DEPARTMENT_NAME        
-------------------- ------------------------------ 
Steven               Executive                      
Neena                Executive                      
Lex                  Executive                      
Alexander            IT                             
Bruce                IT                             
</pre>

<p>Non-equijoins are less frequently used. An example of a non-equijoin:</p>

<pre>
SELECT zip_codes.zip_code, zones.ID AS zip_zone,
       zones.low_zip, zones.high_zip
  FROM zones INNER JOIN zip_codes
       ON zip_codes.zip_code BETWEEN zones.low_zip
                                 AND zones.high_zip
/

ZIP_CODE ZIP_ZONE LOW_ZIP HIGH_ZIP
-------- -------- ------- --------
57000    1        57000   57999 
84006    2        84000   84999 

</pre>

<p>Can you think of another non-equijoin example?</p>
<p>Related articles:<ul>
<li><a href='http://awads.net/wp/2006/07/11/back-to-basics-self-joins/' rel='bookmark' title='Back to basics: self joins'>Back to basics: self joins</a></li>
<li><a href='http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/' rel='bookmark' title='Back to basics: inner joins'>Back to basics: inner joins</a></li>
<li><a href='http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/' rel='bookmark' title='Back to basics: outer joins'>Back to basics: outer joins</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://awads.net/wp/2006/04/26/back-to-basics-equi-and-non-equijoins/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
	</item>
		<item>
		<title>Back to basics: outer joins</title>
		<link>http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/</link>
		<comments>http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/#comments</comments>
		<pubDate>Wed, 22 Mar 2006 15:22:31 +0000</pubDate>
		<dc:creator>Eddie Awad</dc:creator>
				<category><![CDATA[Joins]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[join]]></category>

		<guid isPermaLink="false">http://awads.net/wp/?p=240</guid>
		<description><![CDATA[Continuing the series about joins, today I will review outer joins. An outer join extends the result of an inner join. An outer join returns all rows that satisfy the join condition and also returns some or all of those rows from one table for which no rows from the other satisfy the join condition. [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing <a href="http://awads.net/wp/category/oracle/joins/">the series about joins</a>, today I will review outer joins. An outer join extends the result of an inner join. An outer join returns all rows that satisfy the join condition and also returns some or all of those rows from one table for which no rows from the other satisfy the join condition.</p>

<p>The ANSI SQL syntax of an outer join is:  <span id="more-240"></span></p>

<p><em>FROM t1 { LEFT | RIGHT | FULL } [OUTER] JOIN t2</em></p>

<p>OUTER is optional. If you use LEFT, RIGHT, or FULL, the assumption is that it is an outer join.</p>

<h4>LEFT OUTER JOIN</h4>

<p>LEFT specifies that the results be generated using all rows from t1. For those rows in t1 that don&#8217;t have corresponding rows in t2, NULLs are returned in the result set for the t2 columns.</p>

<p>For example, to list all departments even if they have no employees, you can perform a LEFT OUTER JOIN between the dept and the emp tables:</p>

<pre><code>SELECT dept.dept_name, emp.emp_name
FROM dept LEFT OUTER JOIN emp 
ON dept.dept_id = emp.dept_id

DEPT_NAME  EMP_NAME
---------- ---------
HR         
IT         Eddie                                          

2 rows selected
</code></pre>

<p>A corresponding query using the old join syntax is:</p>

<pre><code>SELECT dept.dept_name, emp.emp_name
FROM dept, emp
WHERE dept.dept_id = emp.dept_id(+)
</code></pre>

<p>The (+) operator following emp.dept_id means that you want to display a row from the dept table, even though there exists no corresponding row in the emp table.</p>

<h4>RIGHT OUTER JOIN</h4>

<p>RIGHT specifies that the results be generated using all rows from t2. For those rows in t2 that don&#8217;t have corresponding rows in t1, NULLs are returned in the result set for the t1 columns.</p>

<p>For example, to list all the employees even if they are not related to any particular department, you can perform a RIGHT OUTER JOIN between the emp and the dept tables:</p>

<pre><code>SELECT dept.dept_name, emp.emp_name
FROM dept RIGHT OUTER JOIN emp 
ON dept.dept_id = emp.dept_id

DEPT_NAME  EMP_NAME  
---------- ---------
           King
IT         Eddie

2 rows selected
</code></pre>

<p>A corresponding query using the old join syntax is:</p>

<pre><code>SELECT dept.dept_name, emp.emp_name
FROM dept, emp 
WHERE dept.dept_id(+) = emp.dept_id
</code></pre>

<p>The (+) operator following dept.dept_id means that you want to display a row from the emp table, even though there exists no corresponding row in the dept table.</p>

<h4>LEFT or RIGHT?</h4>

<p>The LEFT and RIGHT keywords in an outer join query are relative to the position of the tables in the FROM clause. Here is a way to decide which to use, LEFT or RIGHT: look at t1 and t2 in the FROM clause, if t1 is to your left and you want to return all rows from t1, use LEFT JOIN. If t1 is to your right and you want to return all rows from t1, use RIGHT JOIN.</p>

<h4>FULL OUTER JOIN</h4>

<p>FULL specifies that the results be generated using all rows from t1 and all rows from t2. For those rows in t1 that don&#8217;t have corresponding rows in t2, NULLs are returned in the result set for the t2 columns. Additionally, for those rows in t2 that don&#8217;t have corresponding rows in t1, NULLs are returned in the result set for the t1 columns.</p>

<p>For example, to list all the departments (with or without employees), as well as all the employees (with or without a department), use a FULL OUTER JOIN:</p>

<pre><code>SELECT dept.dept_name, emp.emp_name
FROM dept FULL OUTER JOIN emp 
ON dept.dept_id = emp.dept_id


DEPT_NAME  EMP_NAME  
---------- ---------
HR         
IT         Eddie
           King

3 rows selected
</code></pre>

<p>A corresponding query using the old join syntax is:</p>

<pre><code>SELECT dept.dept_name, emp.emp_name
FROM dept, emp 
WHERE dept.dept_id(+) = emp.dept_id(+)
</code></pre>

<p>OOPS! if you execute the above query you get this error:</p>

<pre><code>ORA-01468: a predicate may reference only one outer-joined table
</code></pre>

<p>The fact is that FULL OUTER JOIN is not supported in the old syntax. The outer join operator (+) can appear on only one side of an expression in the join condition, not on both (a workaround is to use a UNION of two SELECT statements).</p>

<p>One other advantage to using ANSI SQL is to overcome the restriction that a condition containing the (+) operator may not use the IN operator and may not be combined with another condition using the OR operator. For example:</p>

<pre><code>SELECT dept.dept_name, emp.emp_name
FROM dept, emp 
WHERE dept.dept_id(+) = emp.dept_id
OR emp.emp_name = 'King'
</code></pre>

<p>Will give you this error:</p>

<pre><code>ORA-01719: outer join operator (+) not allowed in operand of OR or IN
</code></pre>

<p>Here is how you would write the query using the ANSI SQL join and without getting the ORA-01719 error:</p>

<pre><code>SELECT dept.dept_name, emp.emp_name
FROM dept RIGHT OUTER JOIN emp 
ON (dept.dept_id = emp.dept_id
    OR emp.emp_name = 'King')

DEPT_NAME  EMP_NAME  
---------- ---------
HR         King
IT         King
IT         Eddie

3 rows selected
</code></pre>

<p>That concludes my overview of outer joins. Later, I will review the rest of the <a href="http://awads.net/wp/2006/03/16/back-to-basics-cross-joins/">join types</a>&#8230;</p>

<!--adsense-->
<p>Related articles:<ul>
<li><a href='http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/' rel='bookmark' title='Back to basics: inner joins'>Back to basics: inner joins</a></li>
<li><a href='http://awads.net/wp/2006/03/16/back-to-basics-cross-joins/' rel='bookmark' title='Back to basics: cross joins'>Back to basics: cross joins</a></li>
<li><a href='http://awads.net/wp/2006/07/11/back-to-basics-self-joins/' rel='bookmark' title='Back to basics: self joins'>Back to basics: self joins</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
	</item>
		<item>
		<title>Back to basics: inner joins</title>
		<link>http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/</link>
		<comments>http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/#comments</comments>
		<pubDate>Mon, 20 Mar 2006 15:14:12 +0000</pubDate>
		<dc:creator>Eddie Awad</dc:creator>
				<category><![CDATA[Joins]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[join]]></category>

		<guid isPermaLink="false">http://awads.net/wp/?p=238</guid>
		<description><![CDATA[Continuing the series about joins, today it&#8217;s about inner joins. An inner join (aka simple join) is a join of two or more tables that returns only those rows that satisfy the join condition. When you hear people talking about a &#8220;join&#8221;, usually they are referring to an &#8220;inner join&#8221;. For example: create table dept [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing <a href="http://awads.net/wp/category/oracle/joins/">the series about joins</a>, today it&#8217;s about inner joins. An inner join (aka simple join) is a join of two or more tables that returns only those rows that satisfy the join condition. When you hear people talking about a &#8220;join&#8221;, usually they are referring to an &#8220;inner join&#8221;.</p>

<p>For example: <span id="more-238"></span></p>

<pre><code>create table dept (
    dept_id number primary key, 
    dept_name varchar2(100))
/
create table emp (
    emp_id number primary key, 
    emp_name varchar2(100), 
    dept_id number,
    foreign key (dept_id) 
    references dept(dept_id)
)
/
insert into dept values (1, 'HR')
/
insert into dept values (2, 'IT')
/
insert into emp values (1, 'King', null)
/
insert into emp values (2, 'Eddie', 2)
/
</code></pre>

<p>To join the two tables using the old syntax:</p>

<pre><code>select emp.emp_name, dept.dept_name
from emp, dept
where emp.dept_id = dept.dept_id
</code></pre>

<p>Using the new syntax:</p>

<pre><code>select emp.emp_name, dept.dept_name
from emp INNER JOIN dept
ON emp.dept_id = dept.dept_id
</code></pre>

<p>The JOIN keyword is by default INNER, so the INNER keyword in optional in the example above.</p>

<p>Since the join column is named identically in both emp and dept tables, you can use the USING keyword:</p>

<pre><code>select emp.emp_name, dept.dept_name
from emp INNER JOIN dept
USING (dept_id)
</code></pre>

<p>But be careful, if you want to return the join column in the select list, make sure <strong>not</strong> to qualify it. The following:</p>

<pre><code>select dept.dept_id, emp.emp_name, dept.dept_name
from emp INNER JOIN dept
USING (dept_id)
</code></pre>

<p>Returns this error:</p>

<pre><code>ORA-25154: column part of USING clause cannot have qualifier
</code></pre>

<p>There is one additional join option called &#8220;natural join&#8221;, using the NATURAL JOIN clause. With natural joins, you don&#8217;t specify a join condition. A natural join joins on columns with the same names from each table. For example, because the column dept_id is named the same in both emp and dept tables, the following is a legal SQL that implicitly joins emp and dept on dept_id:</p>

<pre><code>select emp.emp_name, dept.dept_name
from emp NATURAL JOIN dept
</code></pre>

<p>Similar to USING, if you want to return the join column in the select list, make sure <strong>not</strong> to qualify it. The following is legal:</p>

<pre><code>select dept_id, emp.emp_name, dept.dept_name
from emp NATURAL JOIN dept
</code></pre>

<p>But, if you use dept.dept_id instead of just dept_id, you get this error:</p>

<pre><code>ORA-25155: column used in NATURAL join cannot have qualifier
</code></pre>

<p>Finally, my preference is to use INNER JOIN&#8230;ON instead of USING or NATURAL JOIN. INNER JOIN&#8230;ON is very clear in showing on what columns you are joining.</p>

<p>Outer joins next&#8230;</p>

<!--adsense-->
<p>Related articles:<ul>
<li><a href='http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/' rel='bookmark' title='Back to basics: outer joins'>Back to basics: outer joins</a></li>
<li><a href='http://awads.net/wp/2007/05/01/back-to-basics-anti-joins-and-semi-joins/' rel='bookmark' title='Back to basics: anti-joins and semi-joins'>Back to basics: anti-joins and semi-joins</a></li>
<li><a href='http://awads.net/wp/2006/03/16/back-to-basics-cross-joins/' rel='bookmark' title='Back to basics: cross joins'>Back to basics: cross joins</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
	
	</item>
		<item>
		<title>Back to basics: cross joins</title>
		<link>http://awads.net/wp/2006/03/16/back-to-basics-cross-joins/</link>
		<comments>http://awads.net/wp/2006/03/16/back-to-basics-cross-joins/#comments</comments>
		<pubDate>Fri, 17 Mar 2006 07:03:29 +0000</pubDate>
		<dc:creator>Eddie Awad</dc:creator>
				<category><![CDATA[Joins]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[join]]></category>

		<guid isPermaLink="false">http://awads.net/wp/?p=237</guid>
		<description><![CDATA[Am I considered old school because I do not use Oracle&#8217;s SQL92 compliant join syntax? After all, it is recommended to follow the standards whenever possible. Starting with Oracle database version 9i, you can use the SQL join syntax that is compliant with the ANSI/ISO SQL92 standard. You also have the option to continue using [...]]]></description>
			<content:encoded><![CDATA[<p>Am I considered old school because I do not use Oracle&#8217;s SQL92 compliant join syntax? After all, it is recommended to follow the standards whenever possible.</p>

<p>Starting with Oracle database version 9i, you can use the SQL join syntax that is compliant with the ANSI/ISO SQL92 standard. You also have the option to continue using the &#8220;old&#8221; syntax  &#8211; that I have been using for years and that I am so used to. But to me, one of the main advantages of using the &#8220;new&#8221; join syntax is that join conditions are separated from the other filter conditions in the WHERE clause, making the query self explanatory as far as join conditions are concerned.</p>

<p>I have decided to break my habit and start using the &#8220;new&#8221; syntax in all my queries (except when I&#8217;m working against Oracle 8i). To that end, I will be writing a series of posts about the different types of joins along with code examples both in the &#8220;old&#8221; and the corresponding &#8220;new&#8221; syntax. Nothing revolutionary, just simple, &#8220;back to basics&#8221; stuff.</p>

<p>Here are the different types of joins that I&#8217;m planning to  review:  <span id="more-237"></span></p>

<ul>
<li>Cross joins</li>
<li>Inner joins</li>
<li>Outer joins</li>
<li>Equi-joins and non equi-joins</li>
<li>Self joins</li>
<li>Anti-joins</li>
<li>Semi-joins</li>
</ul>

<p>I will start with cross joins, a.k.a. Cartesian products. A Cartesian product is returned when you don&#8217;t specify a join condition when joining two tables. Oracle combines each row from the first table with each row from the second table. The number of rows in a  Cartesian product is equal to the number of rows in the first table multiplied by the number of rows in the second table.</p>

<p>Using the old syntax:</p>

<pre><code>select e.first_name, d.department_name
from employees e, departments d
</code></pre>

<p>Using the new syntax:</p>

<pre><code>select e.first_name, d.department_name
from employees e cross join departments d
</code></pre>

<p>Result set:</p>

<pre><code>FIRST_NAME           DEPARTMENT_NAME                
-------------------- ------------------------------ 
Ellen                Administration                 
Sundar               Administration                 
Mozhe                Administration                 
...
...
Matthew              Payroll                        
Jennifer             Payroll                        
Eleni                Payroll                        

2889 rows selected
</code></pre>

<p>2889 = 107 employees * 27 departments.</p>

<p>Cross joins are usually useless and should be avoided.</p>

<p>Using the old syntax, it is easier to forget to include a join condition resulting in an unintentional Cartesian product.</p>

<p>Always include a join condition unless you specifically need a Cartesian product. Join conditions are included in all the other join types.</p>

<p>In my next post, I will review inner joins.</p>

<!--adsense-->
<p>Related articles:<ul>
<li><a href='http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/' rel='bookmark' title='Back to basics: inner joins'>Back to basics: inner joins</a></li>
<li><a href='http://awads.net/wp/2006/03/22/back-to-basics-outer-joins/' rel='bookmark' title='Back to basics: outer joins'>Back to basics: outer joins</a></li>
<li><a href='http://awads.net/wp/2007/05/01/back-to-basics-anti-joins-and-semi-joins/' rel='bookmark' title='Back to basics: anti-joins and semi-joins'>Back to basics: anti-joins and semi-joins</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://awads.net/wp/2006/03/16/back-to-basics-cross-joins/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
	</item>
	</channel>
</rss>

