<?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/"
	>

<channel>
	<title>MacLochlainns Weblog &#187; cartesian products</title>
	<atom:link href="http://blog.mclaughlinsoftware.com/tag/cartesian-products/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mclaughlinsoftware.com</link>
	<description>Michael McLaughlin's Technical Blog</description>
	<lastBuildDate>Mon, 06 Sep 2010 21:21:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Unnatural outcome of natural joins</title>
		<link>http://blog.mclaughlinsoftware.com/2008/05/24/unnatural-outcome-of-natural-joins/</link>
		<comments>http://blog.mclaughlinsoftware.com/2008/05/24/unnatural-outcome-of-natural-joins/#comments</comments>
		<pubDate>Sat, 24 May 2008 03:08:18 +0000</pubDate>
		<dc:creator>maclochlainn</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[cartesian products]]></category>
		<category><![CDATA[cross joins]]></category>
		<category><![CDATA[natural joins]]></category>

		<guid isPermaLink="false">http://maclochlainn.wordpress.com/?p=21</guid>
		<description><![CDATA[You may like the standard syntax of listing tables as comma-delimited lists, rather than using an inner, left, right, full, natural, and cross join syntax. I do! The former method eliminates matching result sets and generally is less tedious. The natural join is my least favorite of these because it can create problems long after [...]]]></description>
			<content:encoded><![CDATA[<p>You may like the standard syntax of listing tables as comma-delimited lists, rather than using an <em>inner</em>, <em>left</em>, <em>right</em>, <em>full</em>, <em>natural</em>, and <em>cross</em> join syntax. I do! The former method eliminates matching result sets and generally is less tedious.</p>
<p>The <em>natural join</em> is my least favorite of these because it can create problems long after the query is written. The problem is an outcome of its design. A natural join matches rows from one table to another by using all matching column names. This query makes a simplifying assumption: Nobody includes a column of the same name in two tables where they may be joined that isn’t a foreign key.</p>
<p>The following is quick example that creates two tables. The <code>VEHICLE</code> table uses the <code>VEHICLE_ID</code> column as a primary key. The <code>WORK_ORDER</code> table uses the <code>VEHICLE_ID</code> column as a foreign key.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> vehicle
<span style="color: #66cc66;">&#40;</span> vehicle_id NUMBER
<span style="color: #66cc66;">,</span> vin VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> work_order
<span style="color: #66cc66;">&#40;</span> work_order_id NUMBER
<span style="color: #66cc66;">,</span> vehicle_id NUMBER<span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> vehicle <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'VIN_NUMBER1'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> vehicle <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'VIN_NUMBER2'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> work_order <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> work_order <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> work_order <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>The following queries resolve the relationship by using an explicit join:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> vehicle v<span style="color: #66cc66;">,</span> work_order wo <span style="color: #993333; font-weight: bold;">WHERE</span> v<span style="color: #66cc66;">.</span>vehicle_id <span style="color: #66cc66;">=</span> wo<span style="color: #66cc66;">.</span>vehicle_id;
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> vehicle v <span style="color: #993333; font-weight: bold;">JOIN</span> work_order wo <span style="color: #993333; font-weight: bold;">ON</span> v<span style="color: #66cc66;">.</span>vehicle_id <span style="color: #66cc66;">=</span> wo<span style="color: #66cc66;">.</span>vehicle_id;
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> vehicle v <span style="color: #993333; font-weight: bold;">JOIN</span> work_order wo <span style="color: #993333; font-weight: bold;">USING</span><span style="color: #66cc66;">&#40;</span>vehicle_id<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>A natural query also resolves the relationship by implicitly finding the columns that share column names, as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> vehicle v <span style="color: #993333; font-weight: bold;">NATURAL</span> <span style="color: #993333; font-weight: bold;">JOIN</span> work_order wo;</pre></div></div>

<p>All of these return a three row result set. The unnatural part of the natural query arrives during maintenance programming when somebody adds a <code>VIN</code> column name to the <code>WORK_ORDER</code> table (let’s say to simplify the ETL to the data warehouse). The code using a natural join isn’t invalidated but its runtime behavior is altered because it now joins both the <code>VEHICLE_ID</code> and <code>VIN</code> columns. Continuing the example, you’d change the table by:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> work_order <span style="color: #993333; font-weight: bold;">ADD</span> <span style="color: #66cc66;">&#40;</span>vin VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>The explicit queries still work after the change. The implicit (natural) query now returns no rows because the <code>VIN</code> column contains all null values, and it is automatically added to the implicit join statement. After updating the <code>VIN</code> column, the query resolves when the data matches <em>but not when the <code>VIN</code> column contains different data</em>. What if the <code>VIN</code> column in <code>WORK_ORDER</code> only contains the make and model portion of the vehicle identification number while the <code>VIN</code> column in <code>VEHICLE</code> contains the complete unique vehicle identifier. You would receive no rows selected from the natural query.</p>
<p>It appears the best thing to do, is avoid natural joins.</p>
<p>I subsequently wrote a post about SQL join semantics. You can find it <a href="http://blog.mclaughlinsoftware.com/oracle-sql-programming/basic-sql-join-semantics/?preview=true&#038;preview_id=1290&#038;preview_nonce=5534f4b090" relation="pingback">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mclaughlinsoftware.com/2008/05/24/unnatural-outcome-of-natural-joins/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
