<?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>Code Spatter &#187; MySQL</title>
	<atom:link href="http://codespatter.com/category/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://codespatter.com</link>
	<description></description>
	<lastBuildDate>Fri, 04 Sep 2009 14:59:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Careful with Numeric Data Types in MySQL</title>
		<link>http://codespatter.com/2008/07/24/careful-with-numeric-data-types-in-mysql/</link>
		<comments>http://codespatter.com/2008/07/24/careful-with-numeric-data-types-in-mysql/#comments</comments>
		<pubDate>Thu, 24 Jul 2008 13:55:04 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Data Types]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=57</guid>
		<description><![CDATA[
	<script type="text/javascript">
	// <![CDATA[
		(function() {
			var links = document.getElementsByTagName('a');
			var query = '&';
			for(var i = 0; i < links.length; i++) {
				if(links[i].href.indexOf('#disqus_thread') >= 0) {
					links[i].innerHTML = 'View Comments';
					query += 'wpid' + i + '=' + encodeURIComponent(links[i].getAttribute('wpid')) + '&';
				}
			}
			document.write('<script charset="utf-8" type="text/javascript" src="http://disqus.com/forums/codespatter/get_num_replies_from_wpid.js?v=2.0' + query + '"><' + '/script>');
		})();
	//]]>
	</script>

	TINYINT can be set to length of 4, but that doesn&#8217;t mean the max value is 9999. A tiny int will always have the same range no matter what size you specify since that isn&#8217;t what it is for with integers. It is the display width for the command line output.
This is what I was [...]


Related posts:<ol><li><a href='http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/' rel='bookmark' title='Permanent Link: How to Break a MySQL Left Join'>How to Break a MySQL Left Join</a> <small>Care must be taken when placing conditions on the results...</small></li><li><a href='http://codespatter.com/2008/07/02/tips-for-mysql-to-postgresql-switch/' rel='bookmark' title='Permanent Link: Tips for MySQL to PostgreSQL Switch'>Tips for MySQL to PostgreSQL Switch</a> <small>If you&#8217;ve decided to move a few tables from MySQL...</small></li><li><a href='http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/' rel='bookmark' title='Permanent Link: How To Use Triggers to Track Changes in MySQL'>How To Use Triggers to Track Changes in MySQL</a> <small>Setting constraints and rules in the database is better than...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>TINYINT can be set to length of 4, but that doesn&#8217;t mean the max value is 9999. A tiny int will always have the same range no matter what size you specify since that isn&#8217;t what it is for with integers. It is the display width for the command line output.</p>
<p>This is what I was able to find in the 
<a  href="http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html" onclick="javascript:pageTracker._trackPageview('/external/dev.mysql.com/doc/refman/5.0/en/numeric-types.html');" >MySQL manual</a>:</p>
<blockquote><p>The display width does not constrain the range of values that can be stored in the column, nor the number of digits that are displayed for values having a width exceeding that specified for the column. </p></blockquote>
<p>Reading the manual for things like this isn&#8217;t something people normally do. I had no idea about this until recently and I&#8217;ve been using MySQL for a long time.</p>
<h3>Reference Chart for Max Signed Integers</h3>
<table border="0">
<tbody>
<tr>
<th scope="row">TINYINT</th>
<td class="align-right">127</td>
</tr>
<tr>
<th scope="row">SMALLINT</th>
<td class="align-right">32767</td>
</tr>
<tr>
<th scope="row">MEDIUMINT</th>
<td class="align-right">8388607</td>
</tr>
<tr>
<th scope="row">INT</th>
<td class="align-right">2147483647</td>
</tr>
<tr>
<th scope="row">BIGINT</th>
<td class="align-right">9223372036854775807</td>
</tr>
</table>
<p>However, CHAR and VARCHAR work as expected with these limits.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2008%2F07%2F24%2Fcareful-with-numeric-data-types-in-mysql%2F';
  addthis_title  = 'Careful+with+Numeric+Data+Types+in+MySQL';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/' rel='bookmark' title='Permanent Link: How to Break a MySQL Left Join'>How to Break a MySQL Left Join</a> <small>Care must be taken when placing conditions on the results...</small></li><li><a href='http://codespatter.com/2008/07/02/tips-for-mysql-to-postgresql-switch/' rel='bookmark' title='Permanent Link: Tips for MySQL to PostgreSQL Switch'>Tips for MySQL to PostgreSQL Switch</a> <small>If you&#8217;ve decided to move a few tables from MySQL...</small></li><li><a href='http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/' rel='bookmark' title='Permanent Link: How To Use Triggers to Track Changes in MySQL'>How To Use Triggers to Track Changes in MySQL</a> <small>Setting constraints and rules in the database is better than...</small></li></ol>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2008/07/24/careful-with-numeric-data-types-in-mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Conditions on Count or Sum in MySQL</title>
		<link>http://codespatter.com/2008/07/22/conditions-on-count-or-sum-in-mysql/</link>
		<comments>http://codespatter.com/2008/07/22/conditions-on-count-or-sum-in-mysql/#comments</comments>
		<pubDate>Tue, 22 Jul 2008 13:55:57 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=42</guid>
		<description><![CDATA[When selecting count, sum, or some other aggregate function, the value isn&#8217;t determined until after the WHERE clause so a condition can&#8217;t be placed there. There is still syntax for specifying a condition for this, it is to use HAVING.
The following example is to count all of the logs an active user has made only [...]


Related posts:<ol><li><a href='http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/' rel='bookmark' title='Permanent Link: How to Break a MySQL Left Join'>How to Break a MySQL Left Join</a> <small>Care must be taken when placing conditions on the results...</small></li><li><a href='http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/' rel='bookmark' title='Permanent Link: How To Use Triggers to Track Changes in MySQL'>How To Use Triggers to Track Changes in MySQL</a> <small>Setting constraints and rules in the database is better than...</small></li><li><a href='http://codespatter.com/2007/05/04/mysql-fun/' rel='bookmark' title='Permanent Link: MySQL Fun'>MySQL Fun</a> <small>Trying to find a way to update a bunch of...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>When selecting count, sum, or some other aggregate function, the value isn&#8217;t determined until after the WHERE clause so a condition can&#8217;t be placed there. There is still syntax for specifying a condition for this, it is to <strong>use HAVING</strong>.</p>
<p>The following example is to count all of the logs an active user has made only if they have more than two logs.</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">SELECT</span> users.user_id, count<span style="color: #66cc66;">&#40;</span>logs.log_id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> count
<span style="color: #993333; font-weight: bold;">FROM</span> users
<span style="color: #993333; font-weight: bold;">JOIN</span> logs
<span style="color: #993333; font-weight: bold;">ON</span> users.user_id <span style="color: #66cc66;">=</span> logs.user_id
<span style="color: #993333; font-weight: bold;">WHERE</span> user.deleted <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> user.user_id
<span style="color: #993333; font-weight: bold;">HAVING</span> count <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">2</span></pre></div></div>

<p>It works the same for sum. Example shows users who have logged less than an hour of time.</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">SELECT</span> users.user_id, sum<span style="color: #66cc66;">&#40;</span>logs.log_time<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> sum
<span style="color: #993333; font-weight: bold;">FROM</span> users
<span style="color: #993333; font-weight: bold;">JOIN</span> logs
<span style="color: #993333; font-weight: bold;">ON</span> users.user_id <span style="color: #66cc66;">=</span> logs.user_id
<span style="color: #993333; font-weight: bold;">WHERE</span> user.deleted <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> user.user_id
<span style="color: #993333; font-weight: bold;">HAVING</span> sum <span style="color: #66cc66;">&lt;</span> <span style="color: #cc66cc;">60</span></pre></div></div>

<p>Common aggregate functions this works with:</p>
<ul>
<li>AVG</li>
<li>COUNT</li>
<li>MAX</li>
<li>MIN</li>
<li>STD</li>
<li>SUM</li>
</ul>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2008%2F07%2F22%2Fconditions-on-count-or-sum-in-mysql%2F';
  addthis_title  = 'Conditions+on+Count+or+Sum+in+MySQL';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/' rel='bookmark' title='Permanent Link: How to Break a MySQL Left Join'>How to Break a MySQL Left Join</a> <small>Care must be taken when placing conditions on the results...</small></li><li><a href='http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/' rel='bookmark' title='Permanent Link: How To Use Triggers to Track Changes in MySQL'>How To Use Triggers to Track Changes in MySQL</a> <small>Setting constraints and rules in the database is better than...</small></li><li><a href='http://codespatter.com/2007/05/04/mysql-fun/' rel='bookmark' title='Permanent Link: MySQL Fun'>MySQL Fun</a> <small>Trying to find a way to update a bunch of...</small></li></ol>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2008/07/22/conditions-on-count-or-sum-in-mysql/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Tips for MySQL to PostgreSQL Switch</title>
		<link>http://codespatter.com/2008/07/02/tips-for-mysql-to-postgresql-switch/</link>
		<comments>http://codespatter.com/2008/07/02/tips-for-mysql-to-postgresql-switch/#comments</comments>
		<pubDate>Wed, 02 Jul 2008 13:38:21 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[regex]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=38</guid>
		<description><![CDATA[If you&#8217;ve decided to move a few tables from MySQL to PostgreSQL, these few tips might help. I won&#8217;t get into any reasons why to move to PostgreSQL or not. There are already 
many discussions on 
the topic.
Create Syntax
The first five listed need to be done in order; the rest can be in any.

Replace mediumint [...]


Related posts:<ol><li><a href='http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/' rel='bookmark' title='Permanent Link: How to Break a MySQL Left Join'>How to Break a MySQL Left Join</a> <small>Care must be taken when placing conditions on the results...</small></li><li><a href='http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/' rel='bookmark' title='Permanent Link: How To Use Triggers to Track Changes in MySQL'>How To Use Triggers to Track Changes in MySQL</a> <small>Setting constraints and rules in the database is better than...</small></li><li><a href='http://codespatter.com/2008/07/24/careful-with-numeric-data-types-in-mysql/' rel='bookmark' title='Permanent Link: Careful with Numeric Data Types in MySQL'>Careful with Numeric Data Types in MySQL</a> <small>TINYINT can be set to length of 4, but that...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve decided to move a few tables from MySQL to PostgreSQL, these few tips might help. I won&#8217;t get into any reasons why to move to PostgreSQL or not. There are already 
<a  href="http://news.ycombinator.com/item?id=184328" onclick="javascript:pageTracker._trackPageview('/external/news.ycombinator.com/item');" >many discussions</a> on 
<a  href="http://news.ycombinator.com/item?id=4861" onclick="javascript:pageTracker._trackPageview('/external/news.ycombinator.com/item');" >the topic</a>.</p>
<h3>Create Syntax</h3>
<p>The first five listed need to be done in order; the rest can be in any.</p>
<ul>
<li>Replace <strong>mediumint </strong>with <strong>int</strong></li>
<li>Replace <strong>tinyint </strong>with <strong>smallint</strong></li>
<li>Replace <strong>int\([0-9]+\) </strong>with <strong>int</strong>. (This is a regular expression that will find any instance of int() where there is at least one number between the parenthesis)</li>
<li><span style="text-decoration: line-through;">Remove all instances of <strong>NOT NULL</strong></span> I don&#8217;t know what I was thinking here.</li>
<li>Replace<strong> int<tt class="regex">\s</tt>+auto_increment</strong> with <strong>SERIAL </strong>(Another regular expression that will catch a case with multiple spaces between int and auto_increment).
<ol>
<li><strong>UPDATE</strong>: try <strong>int(\s+|\s+NOT NULL\s+)auto_increment</strong> instead to catch when not null is in between int and auto.</li>
<li><strong>UPDATE</strong>: try <strong>(smallint|int)(\s+|\s+NOT NULL\s+)auto_increment</strong> so it will catch the case when it is smallint as well.</li>
</ol>
</li>
<li>Remove <strong>ENGINE=MyISAM </strong>(Change if you use a different engine, i.e. innodb)</li>
<li>Remove <strong>DEFAULT CHARSET=latin1</strong> (Change if you use a different character set)</li>
<li>Remove <strong>AUTO_INCREMENT=[0-9]+</strong> (Another regular expression to find all cases of an auto increment number)</li>
<li>Remove <strong>IF NOT EXISTS</strong></li>
<li>Remove all <strong>`</strong></li>
</ul>
<h4>phpMyAdmin</h4>
<p>phpMyAdmin has options when exporting that may make some of these steps unnecessary. If you keep the create sql in a separate file from the insert sql, you save yourself from changing any data that may look like some of the above when it isn&#8217;t actual sql syntax.</p>
<h4>Auto Increment and Serial</h4>
<p>After running the create table SQL, a sequence table will be created for the serial column. This sequence will need to be altered if the auto increment won&#8217;t be starting at one. A query like the one below will need to be done for each table.</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">ALTER</span> SEQUENCE tab_name_col_name_seq RESTART <span style="color: #993333; font-weight: bold;">WITH</span> <span style="color: #808080; font-style: italic;">#;</span></pre></div></div>

<h4>Indexes</h4>
<p>To define a column to be indexed, it is done in a separate query. Remove anything that looks like <strong>KEY username (username)</strong>. The query to run after the create table query should look like</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">INDEX</span> index_name <span style="color: #993333; font-weight: bold;">ON</span> table_name <span style="color: #66cc66;">&#40;</span>column_name<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<h3>Insert Syntax</h3>
<p>The syntax here is pretty close, just one thing needs to be changed.</p>
<ul>
<li>Replace <strong>&#8220;&#8221;</strong> with<strong> \&#8221;.</strong> (MySQL and PostgreSQL use different methods of escaping these quotes.)</li>
</ul>
<p>Make sure the complete inserts option is enabled and extended inserts isn&#8217;t. PosgreSQL doesn&#8217;t support multiple inserts with one query the same way. (As far as I know at the moment)</p>
<h3>Your Mileage May Vary</h3>
<p>This was tested using phpMyAdmin export and phpPgAdmin SQL executing. The regular expressions and other replace commands were done in jEdit. With my few test cases I probably didn&#8217;t catch everything. Let me know how it works out for you.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2008%2F07%2F02%2Ftips-for-mysql-to-postgresql-switch%2F';
  addthis_title  = 'Tips+for+MySQL+to+PostgreSQL+Switch';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/' rel='bookmark' title='Permanent Link: How to Break a MySQL Left Join'>How to Break a MySQL Left Join</a> <small>Care must be taken when placing conditions on the results...</small></li><li><a href='http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/' rel='bookmark' title='Permanent Link: How To Use Triggers to Track Changes in MySQL'>How To Use Triggers to Track Changes in MySQL</a> <small>Setting constraints and rules in the database is better than...</small></li><li><a href='http://codespatter.com/2008/07/24/careful-with-numeric-data-types-in-mysql/' rel='bookmark' title='Permanent Link: Careful with Numeric Data Types in MySQL'>Careful with Numeric Data Types in MySQL</a> <small>TINYINT can be set to length of 4, but that...</small></li></ol>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2008/07/02/tips-for-mysql-to-postgresql-switch/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>How To Use Triggers to Track Changes in MySQL</title>
		<link>http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/</link>
		<comments>http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/#comments</comments>
		<pubDate>Tue, 06 May 2008 13:34:50 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpMyAdmin]]></category>
		<category><![CDATA[Trigger]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=36</guid>
		<description><![CDATA[Setting constraints and rules in the database is better than writing special code to handle the same task since it will prevent another developer from writing a different query that bypasses all of the special code and could leave your database with poor data integrity.

For a long time I was copying info to another table [...]


Related posts:<ol><li><a href='http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/' rel='bookmark' title='Permanent Link: How to Break a MySQL Left Join'>How to Break a MySQL Left Join</a> <small>Care must be taken when placing conditions on the results...</small></li><li><a href='http://codespatter.com/2008/07/24/careful-with-numeric-data-types-in-mysql/' rel='bookmark' title='Permanent Link: Careful with Numeric Data Types in MySQL'>Careful with Numeric Data Types in MySQL</a> <small>TINYINT can be set to length of 4, but that...</small></li><li><a href='http://codespatter.com/2008/07/02/tips-for-mysql-to-postgresql-switch/' rel='bookmark' title='Permanent Link: Tips for MySQL to PostgreSQL Switch'>Tips for MySQL to PostgreSQL Switch</a> <small>If you&#8217;ve decided to move a few tables from MySQL...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Setting constraints and rules in the database is better than writing special code to handle the same task since it will prevent another developer from writing a different query that bypasses all of the special code and could leave your database with poor <strong>data integrity</strong>.</p>
<p><span id="more-36"></span></p>
<p>For a long time I was copying info to another table using a script since MySQL didn&#8217;t support triggers at the time. I have now found this trigger to be more effective at keeping track of everything.</p>
<p>This trigger will copy an old value to a history table if it is changed when someone edits a row. <em>Editor ID</em> and <em>last mod</em> are stored in the original table every time someone edits that row; the time corresponds to when it was changed to its current form.</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TRIGGER</span> <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> history_trigger $$
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TRIGGER</span> history_trigger
BEFORE <span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #993333; font-weight: bold;">ON</span> clients
    <span style="color: #993333; font-weight: bold;">FOR</span> EACH ROW
    BEGIN
        <span style="color: #993333; font-weight: bold;">IF</span> OLD.first_name !<span style="color: #66cc66;">=</span> NEW.first_name
        THEN
                <span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> history_clients
                    <span style="color: #66cc66;">&#40;</span>
                        client_id    ,
                        col          ,
                        value        ,
                        user_id      ,
                        edit_time
                    <span style="color: #66cc66;">&#41;</span>
                    <span style="color: #993333; font-weight: bold;">VALUES</span>
                    <span style="color: #66cc66;">&#40;</span>
                        NEW.client_id,
                        <span style="color: #ff0000;">'first_name'</span>,
                        NEW.first_name,
                        NEW.editor_id,
                        NEW.last_mod
                    <span style="color: #66cc66;">&#41;</span>;
        END <span style="color: #993333; font-weight: bold;">IF</span>;
&nbsp;
        <span style="color: #993333; font-weight: bold;">IF</span> OLD.last_name !<span style="color: #66cc66;">=</span> NEW.last_name
        THEN
                <span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> history_clients
                    <span style="color: #66cc66;">&#40;</span>
                        client_id    ,
                        col          ,
                        value        ,
                        user_id      ,
                        edit_time
                    <span style="color: #66cc66;">&#41;</span>
                    <span style="color: #993333; font-weight: bold;">VALUES</span>
                    <span style="color: #66cc66;">&#40;</span>
                        NEW.client_id,
                        <span style="color: #ff0000;">'last_name'</span>,
                        NEW.last_name,
                        NEW.editor_id,
                        NEW.last_mod
                    <span style="color: #66cc66;">&#41;</span>;
        END <span style="color: #993333; font-weight: bold;">IF</span>;
&nbsp;
    END;
$$</pre></div></div>

<h3>Query Breakdown</h3>
<p>Notice where all of the semi-colons are. If you leave some out, it may take hours to debug your trigger syntax since the error messages don&#8217;t always help.</p>
<p>The OLD and NEW keywords correspond to the value in the row before an update and what is being inserted. Compare these values for each column that you want to track in the table.</p>
<p>An AFTER INSERT trigger should also be used to copy the initial data, and a BEFORE DELETE trigger would be good if you actually remove rows from the database instead of doing a soft delete like I normally do.</p>
<h3>Delimiter is Tricky</h3>
<p>$$ is being used to delimit the end of the two queries since the semi colons are needed for the interior statements.</p>
<h4>Command Line Delimiter</h4>
<p>To use this create-trigger query at the command line, you can add</p>

<div class="wp_syntax"><div class="code"><pre class="sql">DELIMITER $$</pre></div></div>

<p>before the trigger statement and</p>

<div class="wp_syntax"><div class="code"><pre class="sql">DELIMITER ;</pre></div></div>

<p>after it.</p>
<h4>phpMyAdmin Delimiter</h4>
<p>If you are using phpMyAdmin, there should be a small box below the main SQL box where you can enter $$.</p>
<h4>Delimiter in php Scripts</h4>
<p>If you would like to have php scripts create triggers you will need to use the <strong>mysqli_multi_query</strong> function. Below is an example.</p>

<div class="wp_syntax"><div class="code"><pre class="php"><span style="color: #ff0000">$con</span> <span style="color: #66cc66;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MySQLi<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'host'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'user'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'pass'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'db'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">;</span>
&nbsp;
<span style="color: #ff0000">$sql</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'
DROP TRIGGER ... ;
CREATE TRIGGER ... ;
'</span><span style="color: #66cc66;">;</span>
&nbsp;
<span style="color: #ff0000">$con</span><span style="color: #66cc66;">-&amp;</span>gt<span style="color: #66cc66;">;</span>multi_query<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000">$sql</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">;</span></pre></div></div>

<p>Notice that there isn&#8217;t a need for any special delimiter since the multi_query function applies it for you.</p>
<h3>Privileges</h3>
<p>Make sure the database user has the Super privilege since that is needed to create triggers.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2008%2F05%2F06%2Fhow-to-use-triggers-to-track-changes-in-mysql%2F';
  addthis_title  = 'How+To+Use+Triggers+to+Track+Changes+in+MySQL';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/' rel='bookmark' title='Permanent Link: How to Break a MySQL Left Join'>How to Break a MySQL Left Join</a> <small>Care must be taken when placing conditions on the results...</small></li><li><a href='http://codespatter.com/2008/07/24/careful-with-numeric-data-types-in-mysql/' rel='bookmark' title='Permanent Link: Careful with Numeric Data Types in MySQL'>Careful with Numeric Data Types in MySQL</a> <small>TINYINT can be set to length of 4, but that...</small></li><li><a href='http://codespatter.com/2008/07/02/tips-for-mysql-to-postgresql-switch/' rel='bookmark' title='Permanent Link: Tips for MySQL to PostgreSQL Switch'>Tips for MySQL to PostgreSQL Switch</a> <small>If you&#8217;ve decided to move a few tables from MySQL...</small></li></ol>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Swap Insert for Update When Key Exists</title>
		<link>http://codespatter.com/2008/04/30/swap-insert-for-update-when-key-exists/</link>
		<comments>http://codespatter.com/2008/04/30/swap-insert-for-update-when-key-exists/#comments</comments>
		<pubDate>Wed, 30 Apr 2008 14:39:19 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=35</guid>
		<description><![CDATA[When synchronizing tables or databases, sometimes it is useful to have a way to update a row if there is already an entry for a key. Using the MySQL syntax, ON DUPLICATE KEY UPDATE, it is possible to insert a row if it doesn&#8217;t exist or update it if there is already a row with [...]


Related posts:<ol><li><a href='http://codespatter.com/2008/03/20/multiple-inserts-with-a-subquery/' rel='bookmark' title='Permanent Link: Multiple Inserts with a Subquery'>Multiple Inserts with a Subquery</a> <small>Inserting multiple rows into a table is simple. INSERT INTO...</small></li><li><a href='http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/' rel='bookmark' title='Permanent Link: How To Use Triggers to Track Changes in MySQL'>How To Use Triggers to Track Changes in MySQL</a> <small>Setting constraints and rules in the database is better than...</small></li><li><a href='http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/' rel='bookmark' title='Permanent Link: How to Break a MySQL Left Join'>How to Break a MySQL Left Join</a> <small>Care must be taken when placing conditions on the results...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>When synchronizing tables or databases, sometimes it is useful to have a way to update a row if there is already an entry for a key. Using the MySQL syntax, <strong>ON DUPLICATE KEY UPDATE</strong>, it is possible to insert a row if it doesn&#8217;t exist or update it if there is already a row with that key.</p>
<p><span id="more-35"></span></p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> table1 <span style="color: #66cc66;">&#40;</span>
	id,
	text,
	sync_time
<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">VALUES</span>  <span style="color: #66cc66;">&#40;</span>
	<span style="color: #cc66cc;">1</span>,
	<span style="color: #ff0000;">'new'</span>,
	UNIX_TIMESTAMP<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">ON</span> DUPLICATE <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #993333; font-weight: bold;">UPDATE</span>
	text		<span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span>text<span style="color: #66cc66;">&#41;</span>,
	sync_time	<span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span>sync_time<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>To update table1 with all of table2&#8217;s data, a single query can be run without the need of any programming logic.</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> table1 <span style="color: #66cc66;">&#40;</span>id, text, sync_time<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id, text, sync_time <span style="color: #993333; font-weight: bold;">FROM</span> table2<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">ON</span> DUPLICATE <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #993333; font-weight: bold;">UPDATE</span>
	text		<span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span>text<span style="color: #66cc66;">&#41;</span>,
	sync_time	<span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span>sync_time<span style="color: #66cc66;">&#41;</span></pre></div></div>

<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2008%2F04%2F30%2Fswap-insert-for-update-when-key-exists%2F';
  addthis_title  = 'Swap+Insert+for+Update+When+Key+Exists';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2008/03/20/multiple-inserts-with-a-subquery/' rel='bookmark' title='Permanent Link: Multiple Inserts with a Subquery'>Multiple Inserts with a Subquery</a> <small>Inserting multiple rows into a table is simple. INSERT INTO...</small></li><li><a href='http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/' rel='bookmark' title='Permanent Link: How To Use Triggers to Track Changes in MySQL'>How To Use Triggers to Track Changes in MySQL</a> <small>Setting constraints and rules in the database is better than...</small></li><li><a href='http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/' rel='bookmark' title='Permanent Link: How to Break a MySQL Left Join'>How to Break a MySQL Left Join</a> <small>Care must be taken when placing conditions on the results...</small></li></ol>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2008/04/30/swap-insert-for-update-when-key-exists/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Multiple Inserts with a Subquery</title>
		<link>http://codespatter.com/2008/03/20/multiple-inserts-with-a-subquery/</link>
		<comments>http://codespatter.com/2008/03/20/multiple-inserts-with-a-subquery/#comments</comments>
		<pubDate>Thu, 20 Mar 2008 18:36:31 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://codespatter.com/2008/03/20/multiple-inserts-with-a-subquery/</guid>
		<description><![CDATA[Inserting multiple rows into a table is simple.

INSERT INTO table1 &#40;id&#41; VALUES &#40;1&#41;, &#40;2&#41;

But what if you want to use a subquery to replace the explicit query with something more dynamic. This should be possible, however, searching the internet didn&#8217;t get me (or my colleagues) any closer to figuring this out. The obvious attempt of [...]


Related posts:<ol><li><a href='http://codespatter.com/2008/04/30/swap-insert-for-update-when-key-exists/' rel='bookmark' title='Permanent Link: Swap Insert for Update When Key Exists'>Swap Insert for Update When Key Exists</a> <small>When synchronizing tables or databases, sometimes it is useful to...</small></li><li><a href='http://codespatter.com/2008/07/02/tips-for-mysql-to-postgresql-switch/' rel='bookmark' title='Permanent Link: Tips for MySQL to PostgreSQL Switch'>Tips for MySQL to PostgreSQL Switch</a> <small>If you&#8217;ve decided to move a few tables from MySQL...</small></li><li><a href='http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/' rel='bookmark' title='Permanent Link: How to Break a MySQL Left Join'>How to Break a MySQL Left Join</a> <small>Care must be taken when placing conditions on the results...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Inserting multiple rows into a table is simple.</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> table1 <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span> <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;">&#41;</span>, <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>But what if you want to use a subquery to replace the explicit query with something more dynamic. This should be possible, however, searching the internet didn&#8217;t get me (or my colleagues) any closer to figuring this out. The obvious attempt of replacing <em>(1), (2)</em> with <em>(subquery)</em> resulted in the error <em>your subquery returns multiple records</em></p>
<p>In the end we discovered that removing VALUES from the query gave the desired effect.</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> table1 <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> table2<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Executing the above query will insert a row into <em>table1</em> for every result returned by the subquery.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2008%2F03%2F20%2Fmultiple-inserts-with-a-subquery%2F';
  addthis_title  = 'Multiple+Inserts+with+a+Subquery';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2008/04/30/swap-insert-for-update-when-key-exists/' rel='bookmark' title='Permanent Link: Swap Insert for Update When Key Exists'>Swap Insert for Update When Key Exists</a> <small>When synchronizing tables or databases, sometimes it is useful to...</small></li><li><a href='http://codespatter.com/2008/07/02/tips-for-mysql-to-postgresql-switch/' rel='bookmark' title='Permanent Link: Tips for MySQL to PostgreSQL Switch'>Tips for MySQL to PostgreSQL Switch</a> <small>If you&#8217;ve decided to move a few tables from MySQL...</small></li><li><a href='http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/' rel='bookmark' title='Permanent Link: How to Break a MySQL Left Join'>How to Break a MySQL Left Join</a> <small>Care must be taken when placing conditions on the results...</small></li></ol>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2008/03/20/multiple-inserts-with-a-subquery/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>How to Break a MySQL Left Join</title>
		<link>http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/</link>
		<comments>http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/#comments</comments>
		<pubDate>Tue, 19 Feb 2008 14:45:15 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/</guid>
		<description><![CDATA[Care must be taken when placing conditions on the results of the right-hand table of a LEFT JOIN because it could easily become a normal JOIN since MySQL is using a NULL row for every column in the right-hand table when no records exist.

Since I like to use a soft delete on all tables (hidden [...]


Related posts:<ol><li><a href='http://codespatter.com/2008/07/22/conditions-on-count-or-sum-in-mysql/' rel='bookmark' title='Permanent Link: Conditions on Count or Sum in MySQL'>Conditions on Count or Sum in MySQL</a> <small>When selecting count, sum, or some other aggregate function, the...</small></li><li><a href='http://codespatter.com/2008/07/02/tips-for-mysql-to-postgresql-switch/' rel='bookmark' title='Permanent Link: Tips for MySQL to PostgreSQL Switch'>Tips for MySQL to PostgreSQL Switch</a> <small>If you&#8217;ve decided to move a few tables from MySQL...</small></li><li><a href='http://codespatter.com/2008/07/24/careful-with-numeric-data-types-in-mysql/' rel='bookmark' title='Permanent Link: Careful with Numeric Data Types in MySQL'>Careful with Numeric Data Types in MySQL</a> <small>TINYINT can be set to length of 4, but that...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Care must be taken when placing conditions on the results of the right-hand table of a <em>LEFT JOIN</em> because it could easily become a normal <em>JOIN </em>since <strong>MySQL is using a <em>NULL</em> row for every column in the right-hand table when no records exist</strong><em>.</em></p>
<p><span id="more-24"></span></p>
<p>Since I like to use a soft delete on all tables (hidden but not deleted), I need to put a condition to alter the results from the right-hand table. The proper way to place a condition on this table is to use:</p>

<div class="wp_syntax"><div class="code"><pre class="sql">...
<span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #66cc66;">&#40;</span>
	right_table.foo <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'bar'</span>  <span style="color: #808080; font-style: italic;">-- the condition you want</span>
		<span style="color: #993333; font-weight: bold;">OR</span>
	right_table.foo <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NULL</span>  <span style="color: #808080; font-style: italic;">-- it's cool if it's empty</span>
<span style="color: #66cc66;">&#41;</span>
...</pre></div></div>

<h3>Here is an Example</h3>
<p>Here are some example SQL statements to see exactly what is happening. First we <strong>create two tables</strong> with a one-to-many relationship.</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> tasks <span style="color: #66cc66;">&#40;</span>  <span style="color: #808080; font-style: italic;">-- left</span>
 	task_id MEDIUMINT<span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">5</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>
 		<span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> ,
	 task_text TEXT <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> ,
	 task_deleted TINYINT<span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> ,
	 task_last_mod INT<span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">11</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> ,
	 task_created INT<span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">11</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>
	<span style="color: #66cc66;">&#41;</span> ENGINE <span style="color: #66cc66;">=</span> MYISAM;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> logs <span style="color: #66cc66;">&#40;</span>  <span style="color: #808080; font-style: italic;">-- right</span>
	 log_id MEDIUMINT<span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">6</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>
	 	<span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> ,
	 task_id MEDIUMINT<span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">5</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> ,
	 log_text TEXT <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> ,
	 log_length INT<span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">11</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> ,
	 log_deleted TINYINT<span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> ,
	 log_last_mod INT<span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">11</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> ,
	 log_created INT<span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">11</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>
<span style="color: #66cc66;">&#41;</span> ENGINE <span style="color: #66cc66;">=</span> MYISAM;</pre></div></div>

<p>After creating the tables we are ready to <strong>add some testing data</strong>.</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> tasks <span style="color: #66cc66;">&#40;</span>
 	task_id ,
 	task_text ,
	task_deleted ,
	task_last_mod ,
	task_created
<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span>
	 <span style="color: #cc66cc;">1</span> , <span style="color: #ff0000;">'Get me a beer.'</span>, <span style="color: #cc66cc;">0</span>,
	 <span style="color: #cc66cc;">1203372686</span> , <span style="color: #cc66cc;">1203372686</span>
<span style="color: #66cc66;">&#41;</span>, <span style="color: #66cc66;">&#40;</span>
	 <span style="color: #cc66cc;">2</span> , <span style="color: #ff0000;">'Something ridiculous.'</span>, <span style="color: #cc66cc;">0</span>,
	 <span style="color: #cc66cc;">1203372686</span> , <span style="color: #cc66cc;">1203372686</span>
<span style="color: #66cc66;">&#41;</span>, <span style="color: #66cc66;">&#40;</span>
	 <span style="color: #cc66cc;">3</span> , <span style="color: #ff0000;">'a logless task'</span>, <span style="color: #cc66cc;">0</span>,
	 <span style="color: #cc66cc;">1203372686</span>, <span style="color: #cc66cc;">1203372686</span>
<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> logs <span style="color: #66cc66;">&#40;</span>
	 log_id ,
	 task_id ,
	 log_text ,
	 log_length ,
	 log_deleted ,
	 log_last_mod ,
	 log_created
<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span>
	 <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #ff0000;">'got a beer'</span>, <span style="color: #cc66cc;">120</span>,
	 <span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1203372686</span>, <span style="color: #cc66cc;">1203372686</span>
<span style="color: #66cc66;">&#41;</span>, <span style="color: #66cc66;">&#40;</span>
	 <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #ff0000;">'this took forever'</span>, <span style="color: #cc66cc;">900</span>,
	 <span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1203372686</span>, <span style="color: #cc66cc;">1203372686</span>
<span style="color: #66cc66;">&#41;</span>, <span style="color: #66cc66;">&#40;</span>
	 <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #ff0000;">'a deleted one'</span>, <span style="color: #cc66cc;">900</span>,
	 <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1203372686</span>, <span style="color: #cc66cc;">1203372686</span>
<span style="color: #66cc66;">&#41;</span>, <span style="color: #66cc66;">&#40;</span>
	 <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #ff0000;">'moar beer'</span>, <span style="color: #cc66cc;">120</span>,
	 <span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">1203372686</span>, <span style="color: #cc66cc;">1203372686</span>
<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<h3>Simple SELECT</h3>
<p>This will get <strong>all</strong> tasks, count the logs, and sum the logged time whether there is a log or not for the task.</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">SELECT</span> task_text, count<span style="color: #66cc66;">&#40;</span>tasks.task_id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> log_count,
	 sum<span style="color: #66cc66;">&#40;</span>log_length<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> total_time
<span style="color: #993333; font-weight: bold;">FROM</span> tasks <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> logs
<span style="color: #993333; font-weight: bold;">ON</span> tasks.task_id <span style="color: #66cc66;">=</span> logs.task_id
<span style="color: #993333; font-weight: bold;">WHERE</span> task_deleted <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> logs.task_id;</pre></div></div>

<p>This query produces expected results as seen below.</p>
<table border="0">
<tbody>
<tr>
<th scope="col">task_text</th>
<th scope="col">log_count</th>
<th scope="col">total_time</th>
</tr>
<tr>
<td>a logless task</td>
<td>1</td>
<td><em>NULL</em></td>
</tr>
<tr>
<td>Get me a beer.</td>
<td>3</td>
<td>1140</td>
</tr>
<tr>
<td>Something ridiculous.</td>
<td>1</td>
<td>900</td>
</tr>
</tbody>
</table>
<h3>Improper Conditional SELECT</h3>
<p>If we were to place a condition on the right-hand table to limit the results to only count and sum the logs that are active, <em>at first we might try</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">SELECT</span> task_text, count<span style="color: #66cc66;">&#40;</span>tasks.task_id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> log_count,
	 sum<span style="color: #66cc66;">&#40;</span>log_length<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> total_time
<span style="color: #993333; font-weight: bold;">FROM</span> tasks <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> logs <span style="color: #993333; font-weight: bold;">ON</span> tasks.task_id <span style="color: #66cc66;">=</span> logs.task_id
<span style="color: #993333; font-weight: bold;">WHERE</span> task_deleted <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>
<span style="color: #993333; font-weight: bold;">AND</span> log_deleted <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>  <span style="color: #808080; font-style: italic;">-- this breaks the left join</span>
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> logs.task_id;</pre></div></div>

<p>This produces the results in the following table. Notice that the logless task has disappeared and that the log count and sum for the <em>Get me a beer</em> task has changed to the desired values. <strong>This is the same as a normal JOIN statement</strong>.</p>
<table border="0">
<tbody>
<tr>
<th scope="col">task_text</th>
<th scope="col">log_count</th>
<th scope="col">total_time</th>
</tr>
<tr>
<td>Get me a beer.</td>
<td>2</td>
<td>240</td>
</tr>
<tr>
<td>Something ridiculous.</td>
<td>1</td>
<td>900</td>
</tr>
</tbody>
</table>
<h3>The Proper Way</h3>
<p>The proper way to achieve the desired results is to <strong>use the following</strong> query:</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">SELECT</span> task_text, count<span style="color: #66cc66;">&#40;</span>tasks.task_id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> log_count,
	 sum<span style="color: #66cc66;">&#40;</span>log_length<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> total_time
<span style="color: #993333; font-weight: bold;">FROM</span> tasks <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> logs <span style="color: #993333; font-weight: bold;">ON</span> tasks.task_id <span style="color: #66cc66;">=</span> logs.task_id
<span style="color: #993333; font-weight: bold;">WHERE</span> task_deleted <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>
<span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#40;</span>
	log_deleted <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>
	<span style="color: #993333; font-weight: bold;">OR</span>
	log_deleted <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NULL</span>
<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> logs.task_id;</pre></div></div>

<p>Producing:</p>
<table border="0">
<tbody>
<tr>
<th scope="col">task_text</th>
<th scope="col">log_count</th>
<th scope="col">total_time</th>
</tr>
<tr>
<td>a logless task</td>
<td>1</td>
<td><em>NULL</em></td>
</tr>
<tr>
<td>Get me a beer.</td>
<td>2</td>
<td>240</td>
</tr>
<tr>
<td>Something ridiculous.</td>
<td>1</td>
<td>900</td>
</tr>
</tbody>
</table>
<p>As you can see the <em>logless task</em> is back and the values for <em>Get me a beer</em> are accurate.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2008%2F02%2F19%2Fhow-to-break-a-mysql-left-join%2F';
  addthis_title  = 'How+to+Break+a+MySQL+Left+Join';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2008/07/22/conditions-on-count-or-sum-in-mysql/' rel='bookmark' title='Permanent Link: Conditions on Count or Sum in MySQL'>Conditions on Count or Sum in MySQL</a> <small>When selecting count, sum, or some other aggregate function, the...</small></li><li><a href='http://codespatter.com/2008/07/02/tips-for-mysql-to-postgresql-switch/' rel='bookmark' title='Permanent Link: Tips for MySQL to PostgreSQL Switch'>Tips for MySQL to PostgreSQL Switch</a> <small>If you&#8217;ve decided to move a few tables from MySQL...</small></li><li><a href='http://codespatter.com/2008/07/24/careful-with-numeric-data-types-in-mysql/' rel='bookmark' title='Permanent Link: Careful with Numeric Data Types in MySQL'>Careful with Numeric Data Types in MySQL</a> <small>TINYINT can be set to length of 4, but that...</small></li></ol>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>MySQL Fun</title>
		<link>http://codespatter.com/2007/05/04/mysql-fun/</link>
		<comments>http://codespatter.com/2007/05/04/mysql-fun/#comments</comments>
		<pubDate>Fri, 04 May 2007 06:27:16 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=4</guid>
		<description><![CDATA[Trying to find a way to update a bunch of records in the request table by changing request_taken_time to a value in another table. The problem is, there are multiple records in the history table so there will be duplicate queries and it may not get the most recent time which is what is wanted. [...]


Related posts:<ol><li><a href='http://codespatter.com/2008/07/02/tips-for-mysql-to-postgresql-switch/' rel='bookmark' title='Permanent Link: Tips for MySQL to PostgreSQL Switch'>Tips for MySQL to PostgreSQL Switch</a> <small>If you&#8217;ve decided to move a few tables from MySQL...</small></li><li><a href='http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/' rel='bookmark' title='Permanent Link: How to Break a MySQL Left Join'>How to Break a MySQL Left Join</a> <small>Care must be taken when placing conditions on the results...</small></li><li><a href='http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/' rel='bookmark' title='Permanent Link: How To Use Triggers to Track Changes in MySQL'>How To Use Triggers to Track Changes in MySQL</a> <small>Setting constraints and rules in the database is better than...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Trying to find a way to update a bunch of records in the request table by changing request_taken_time to a value in another table. The problem is, there are multiple records in the history table so there will be duplicate queries and it may not get the most recent time which is what is wanted. I can&#8217;t use group by on an update and if I can&#8217;t use group by then I can&#8217;t use the MAX function. So it will basically update the records multiple times and won&#8217;t get the highest value like I need it to.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2007%2F05%2F04%2Fmysql-fun%2F';
  addthis_title  = 'MySQL+Fun';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2008/07/02/tips-for-mysql-to-postgresql-switch/' rel='bookmark' title='Permanent Link: Tips for MySQL to PostgreSQL Switch'>Tips for MySQL to PostgreSQL Switch</a> <small>If you&#8217;ve decided to move a few tables from MySQL...</small></li><li><a href='http://codespatter.com/2008/02/19/how-to-break-a-mysql-left-join/' rel='bookmark' title='Permanent Link: How to Break a MySQL Left Join'>How to Break a MySQL Left Join</a> <small>Care must be taken when placing conditions on the results...</small></li><li><a href='http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/' rel='bookmark' title='Permanent Link: How To Use Triggers to Track Changes in MySQL'>How To Use Triggers to Track Changes in MySQL</a> <small>Setting constraints and rules in the database is better than...</small></li></ol>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2007/05/04/mysql-fun/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
