<?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>tc software</title>
	<atom:link href="http://tcsoftware.net/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://tcsoftware.net/blog</link>
	<description>Bespoke software development</description>
	<lastBuildDate>Tue, 07 Feb 2012 23:14:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Installing Class 1 StartSSL Certificate on Debian</title>
		<link>http://tcsoftware.net/blog/2012/02/installing-class-1-startssl-certificate-on-debian/</link>
		<comments>http://tcsoftware.net/blog/2012/02/installing-class-1-startssl-certificate-on-debian/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 23:10:00 +0000</pubDate>
		<dc:creator>tc</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[StartSSL]]></category>
		<category><![CDATA[TLS]]></category>

		<guid isPermaLink="false">http://tcsoftware.net/blog/?p=83</guid>
		<description><![CDATA[To install a Class 1 StartSSL Certificate on Debian first you will need to obtain both your private key and certificate from StartSSL&#8217;s website and upload them to your server. I&#8217;d recommend that you keep both the Webserver SSL/TLS Certificate &#8230; <a href="http://tcsoftware.net/blog/2012/02/installing-class-1-startssl-certificate-on-debian/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>To install a Class 1 StartSSL Certificate on Debian first you will need to obtain both your private key and certificate from StartSSL&#8217;s website and upload them to your server. I&#8217;d recommend that you keep both the Webserver SSL/TLS Certificate and StartSSL&#8217;s CA Certificates in a secure directory for the website it is to be used by (i.e. a directory not accessible by HTTP).</p>
<p><strong>Step 1:</strong> Assuming you have encrypted your private key when generating it on StartSSL&#8217;s website you will need to decrypt the key on your server or a password will be required whenever the HTTP server restarts.<br />
Doing this is simple, login via SSH to your server and go to the directory containing your certificate and (assuming the file is named ssl.key) type the following:</p>
<p style="padding-left: 30px;">openssl rsa -in ssl.key -out ssl.key</p>
<p>openssl should then request the password for the private key and decrypt it.</p>
<p><strong>Step 2:</strong> Once the key is decrypted we need to download StartSSL&#8217;s Certificate Authority Certificates. For the Class 1 certificate we only need ca.pem and sub.class1.server.ca.pem<br />
So again in your SSH console type the following 2 commands:</p>
<p style="padding-left: 30px;">wget https://www.startssl.com/certs/ca.pem<br />
wget https://www.startssl.com/certs/sub.class1.server.ca.pem</p>
<p>Once you have downloaded these files you should set the permissions to read only by the file owner (chmod 400 *)</p>
<p><strong>Step 3:</strong> Assuming you have already enabled SSL for your HTTP server you only need add the SSL certificate and CA Certificates to your virtual host, in apache we do this by creating something like the following:</p>
<p style="padding-left: 30px;font-size: 10pt">&lt;VirtualHost *:443&gt;<br />
ServerName example.com<br />
ServerAlias www.example.com<br />
DocumentRoot /var/www/vhosts/example.com/public_html/<br />
SSLEngine on<br />
SSLProtocol all -SSLv2<br />
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM<br />
SSLCertificateFile /path/to/ssl/certificate.crt<br />
SSLCertificateKeyFile /path/to/ssl/certificate.key<br />
SSLCertificateChainFile /path/to/ssl/ca/certificate/sub.class1.server.ca.pem<br />
SSLCACertificateFile /path/to/ssl/ca/certificate/ca.pem<br />
SetEnvIf User-Agent &#8220;.*MSIE.*&#8221; nokeepalive ssl-unclean-shutdown<br />
&lt;VirtualHost&gt;</p>
<p>If you have not already enabled SSL in apache you can do so by moving the file mods-available/ssl.load to the mods-enabled directory (typically these can be found in /etc/apache2/)</p>
<p>All that is left is to restart the HTTP server (for apache this would be /etc/init.d/apache2 restart) and as long as there are no errors your certificate is ready for use!</p>
]]></content:encoded>
			<wfw:commentRss>http://tcsoftware.net/blog/2012/02/installing-class-1-startssl-certificate-on-debian/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Converting to and from VB6 Date to Unix / POSIX time</title>
		<link>http://tcsoftware.net/blog/2012/01/converting-to-and-from-vb6-date-to-unix-posix-time/</link>
		<comments>http://tcsoftware.net/blog/2012/01/converting-to-and-from-vb6-date-to-unix-posix-time/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 10:59:10 +0000</pubDate>
		<dc:creator>tc</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[VB6]]></category>

		<guid isPermaLink="false">http://tcsoftware.net/blog/?p=72</guid>
		<description><![CDATA[Visual Basic 6 as a language may slowly be falling into disuse and is a language which is no longer supported by Microsoft but we still need to interface old and new systems from time to time. The rise of &#8230; <a href="http://tcsoftware.net/blog/2012/01/converting-to-and-from-vb6-date-to-unix-posix-time/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Visual Basic 6 as a language may slowly be falling into disuse and is a language which is no longer supported by Microsoft but we still need to interface old and new systems from time to time.<br />
The rise of PHP, Ruby and other languages which have roots in the Unix environment converting date time values from Unix time to the IEEE 64 bit value used by VBScript is common task which can sometimes prove to be a bit of a headache. However, the conversion is actually quite simple.</p>
<p>Unix represents time by counting the seconds since the Unix epoch, which is January 1st 1970 00:00:00 UTC. Most systems today use a 32 bit signed integer to hold this value allowing it to represent dates and times between December 13th 1901 and January 19th 2038</p>
<p>Thus to convert Unix Time to a Date value useful to Visual Basic we need only add the number of seconds in the value to the date 1/1/1970 00:00:00 UTC. This can easily be done using the DateAdd function:<br />
<code style="margin-left: 4em; display: block;"></p>
<p><span style="color: #3366ff;">Function</span> FromUnixTime(UnixTime <span style="color: #3366ff;">As Long</span>) <span style="color: #3366ff;">As Date</span><br />
FromUnixTime = DateAdd("s", UnixTime, DateSerial(1970, 1, 1))<br />
<span style="color: #3366ff;">End Function</span></code></p>
<p>Converting from Visual Basic to Unix Time is just as simple save that Technically Visual Basic can represent Dates and Times outside that which Unix Time can represent. To do the conversion we need only find the number of seconds from Unix epoch to our target date, for which we can use the DateDiff function:<br />
<code style="margin-left: 4em; display: block;"><br />
<span style="color: #3366ff;">Function</span> ToUnixTime(time <span style="color: #3366ff;">As Date</span>) <span style="color: #3366ff;">As Long</span><br />
ToUnixTime = DateDiff("s", DateSerial(1970, 1, 1), time)<br />
<span style="color: #3366ff;">End Function</span><br />
</code></p>
<p>Note: Should the date value in Visual Basic be beyond a date which Unix Time can represent then ToUnixTime will throw and overflow error.</p>
]]></content:encoded>
			<wfw:commentRss>http://tcsoftware.net/blog/2012/01/converting-to-and-from-vb6-date-to-unix-posix-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP SoapClient Authentication</title>
		<link>http://tcsoftware.net/blog/2011/08/php-soapclient-authentication/</link>
		<comments>http://tcsoftware.net/blog/2011/08/php-soapclient-authentication/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 08:53:34 +0000</pubDate>
		<dc:creator>tc</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://tcsoftware.net/blog/?p=47</guid>
		<description><![CDATA[SoapClientAuth replaces the SoapClient class in PHP. This Soap Client, whose interface and operation is identical to the SoapClient class, will perform HTTP authenticaion for SOAP messages and when downloading WSDL over HTTP &#38; HTTPS. Out of the box PHPs &#8230; <a href="http://tcsoftware.net/blog/2011/08/php-soapclient-authentication/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://tcsoftware.net/blog/wp-content/uploads/2011/08/xml.jpg"><img class="size-full wp-image-48 alignright" title="xml" src="http://tcsoftware.net/blog/wp-content/uploads/2011/08/xml.jpg" alt="" width="128" height="128" /></a><a title="SoapClientAuth Download" onclick="javascript: _gaq.push(['_trackPageview', '/downloads/php/download.php?file=SoapClientAuth']);" href="http://tcsoftware.net/downloads/php/download.php?file=SoapClientAuth">SoapClientAuth</a> replaces the SoapClient class in PHP. This Soap Client, whose interface and operation is identical to the SoapClient class, will perform HTTP authenticaion for SOAP messages and when downloading WSDL over HTTP &amp; HTTPS.</p>
<p>Out of the box PHPs SoapClient class is unable to authenticate via HTTP when downloading WSDL and is unable to authenticate to web services protected by NTLM authentication. SoapClientAuth however will authenticate to Basic, Digest and NTLM web services even if the WSDL file itself is protected by HTTP authentication.</p>
<p>You should use this class as you would use the <a title="SoapClient documentation" onclick="javascript: _gaq.push(['_trackPageview', '/downloads/php/download.php?file=SoapClientAuth']);" href="http://www.php.net/manual/en/class.soapclient.php">SoapClient class </a>and simply provide the username and password to the service in the options (login and password) parameter of the constructor. For Example:<br />
<span class="notranslate">
<pre>$soapClient = new SoapClientAuth('http://url.to.my/soap/service',
            array(
                'login' =&gt; 'username',
                'password' =&gt; 'password'
            ));

$soapClient-&gt;MyMethod();</pre>
<p></span><br />
<a title="SoapClientAuth Download" onclick="javascript: _gaq.push(['_trackPageview', '/downloads/php/download.php?file=SoapClientAuth']);" href="http://tcsoftware.net/downloads/php/download.php?file=SoapClientAuth">Download SoapClientAuth</a></p>
<p>Requirements:<br />
PHP 5.0<br />
curl</p>
<p>SoapClientAuth is distributed and licensed under the terms of the GNU General Public License.<br />
Copyright tc software © 2011</p>
]]></content:encoded>
			<wfw:commentRss>http://tcsoftware.net/blog/2011/08/php-soapclient-authentication/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Crystal Reports Redistributable Download (.NET 2005)</title>
		<link>http://tcsoftware.net/blog/2011/05/crystal-reports-redistributable-download-net-2005/</link>
		<comments>http://tcsoftware.net/blog/2011/05/crystal-reports-redistributable-download-net-2005/#comments</comments>
		<pubDate>Thu, 26 May 2011 08:39:31 +0000</pubDate>
		<dc:creator>tc</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Crystal Reports]]></category>

		<guid isPermaLink="false">http://tcsoftware.net/blog/?p=41</guid>
		<description><![CDATA[Redistributable installation packs for Crystal Reports as used in Visual Studio 2005. These msi&#8217;s where built from the merge modules as supplied by Business Objects, they will install the Crystal Reporting engine and assemblies required by any Applications (both Desktop &#8230; <a href="http://tcsoftware.net/blog/2011/05/crystal-reports-redistributable-download-net-2005/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Redistributable installation packs for Crystal Reports as used in Visual Studio 2005. These msi&#8217;s where built from the merge modules as supplied by Business Objects, they will install the Crystal Reporting engine and assemblies required by any Applications (both Desktop and ASP.NET) utilizing Crystal. Simply select the appropriate file for your platform, download and install. Then restart any application which uses Crystal Reports (Restart IIS for web applications)</p>
<p><a href="/downloads/windows/dotnet/2.0/crystal-redist/cr_net_2005_x86.msi" onClick="javascript: _gaq.push(['_trackPageview', '/downloads/windows/dotnet/2.0/crystal-redist/cr_net_2005_x86.msi']);">Crystal Reports Redistributable for x86 systems</a><br />
<a href="/downloads/windows/dotnet/2.0/crystal-redist/cr_net_2005_x64.msi" onClick="javascript: _gaq.push(['_trackPageview', '/downloads/windows/dotnet/2.0/crystal-redist/cr_net_2005_x64.msi']);">Crystal Reports Redistributable for x64 systems</a><br />
<a href="/downloads/windows/dotnet/2.0/crystal-redist/cr_net_2005_i64.msi" onClick="javascript: _gaq.push(['_trackPageview', '/downloads/windows/dotnet/2.0/crystal-redist/cr_net_2005_i64.msi']);">Crystal Reports Redistributable for i64 systems</a></p>
<p>.NET 2.0 is required, the installers will take you to Microsoft&#8217;s website if it is not found on your system.<br />
These installations will install the following assemblies (Public Key Token: 692fbea5521e1304, Version 10.2.3600.0):</p>
<p>CrystalDecisions.CrystalReports.Engine<br />
CrystalDecisions.CrystalReports.Engine.resources<br />
CrystalDecisions.Data.AdoDotNetInterop<br />
CrystalDecisions.Enterprise.Desktop.Report<br />
CrystalDecisions.Enterprise.Framework<br />
CrystalDecisions.Enterprise.InfoStore<br />
CrystalDecisions.Enterprise.PluginManager<br />
CrystalDecisions.Enterprise.Viewing.ReportSource<br />
CrystalDecisions.KeyCode<br />
CrystalDecisions.ReportAppServer.ClientDoc<br />
CrystalDecisions.ReportAppServer.CommLayer<br />
CrystalDecisions.ReportAppServer.CommonControls<br />
CrystalDecisions.ReportAppServer.CommonObjectModel<br />
CrystalDecisions.ReportAppServer.Controllers<br />
CrystalDecisions.ReportAppServer.CubeDefModel<br />
CrystalDecisions.ReportAppServer.DataDefModel<br />
CrystalDecisions.ReportAppServer.DataSetConversion<br />
CrystalDecisions.ReportAppServer.ObjectFactory<br />
CrystalDecisions.ReportAppServer.ReportDefModel<br />
CrystalDecisions.ReportAppServer.XmlSerialize<br />
CrystalDecisions.ReportSource<br />
CrystalDecisions.ReportSource.resources<br />
CrystalDecisions.Shared<br />
CrystalDecisions.Shared.resources<br />
CrystalDecisions.Web<br />
CrystalDecisions.Web.resources<br />
CrystalDecisions.Windows.Forms<br />
CrystalDecisions.Windows.Forms.resources</p>
]]></content:encoded>
			<wfw:commentRss>http://tcsoftware.net/blog/2011/05/crystal-reports-redistributable-download-net-2005/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to create a silent ringtone for the iPhone</title>
		<link>http://tcsoftware.net/blog/2011/05/how-to-create-a-silent-ringtone-for-the-iphone/</link>
		<comments>http://tcsoftware.net/blog/2011/05/how-to-create-a-silent-ringtone-for-the-iphone/#comments</comments>
		<pubDate>Wed, 18 May 2011 11:52:22 +0000</pubDate>
		<dc:creator>tc</dc:creator>
				<category><![CDATA[iPhone]]></category>
		<category><![CDATA[ringtone]]></category>

		<guid isPermaLink="false">http://tcsoftware.net/blog/?p=31</guid>
		<description><![CDATA[Silencing the ringtone on your phone is a useful feature for call screening but by default the iPhone is not able to turn off ringtones for individual contacts. Fortunately creating a ringtone is quite simple and creating a silent tone &#8230; <a href="http://tcsoftware.net/blog/2011/05/how-to-create-a-silent-ringtone-for-the-iphone/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Silencing the ringtone on your phone is a useful feature for call screening but by default the iPhone is not able to turn off ringtones for individual contacts. Fortunately creating a ringtone is quite simple and creating a silent tone only requires an empty sound file and iTunes.</p>
<p>First, to create a silent tone <small><a href="http://tcsoftware.net/downloads/iPhone/Silence.m4r" onclick="_gaq.push(['_trackPageview', '/downloads/iPhone/Silence.m4r']);">(download)</a></small>, you should create an empty sound file using a sound editor (such as <a href="http://audacity.sourceforge.net/">Audacity</a>). To avoid any problems with any iPhone updates I would recommend creating a file with at least 1 second of silence. Audacity itself can generate this for you by clicking on &#8216;Generate&#8217; and then &#8216;Silence&#8217; on the menu bar. The silent file can be in any format supported by iTunes (wave file, mp3, AAC, etc&#8230;)</p>
<p>Next to convert the sound file to a ring tone you should import the file into your iTunes library (Note: the maximum length for a ring tone is 40 seconds) and use iTunes to convert the file into an AAC file (right click on the file in iTunes and click &#8216;Create AAC Version&#8217;.</p>
<p>Once iTunes has created an AAC copy of the file simply drag this out onto your desktop and change the file extension to m4r (i.e. silence.m4a should be changed to silence.m4r).</p>
<p>Return to iTunes and delete the AAC copy of your sound file (if you do not iTunes will not import the ring tone) and then drag the ring tone file on your desktop into iTunes. Then simply import the ring tone into your iPhone!</p>
<p>If you&#8217;re using a silent tone for call screening its often useful to create a contact on your phone and set the ringtone for the contact to your silent ring tone. Then simply add numbers to this contact that  you do not want the phone to play a tone to.</p>
<p>You can also download our copy of the silent ringtone by clicking <a href="http://tcsoftware.net/downloads/iPhone/Silence.m4r" onclick="_gaq.push(['_trackPageview', '/downloads/iPhone/Silence.m4r']);">here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tcsoftware.net/blog/2011/05/how-to-create-a-silent-ringtone-for-the-iphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Capturing Return / Enter in DataGridViewTextBoxCell&#8217;s in a DataGridView</title>
		<link>http://tcsoftware.net/blog/2011/03/capturing-return-enter-in-datagridviewtextboxcells-in-a-datagridview/</link>
		<comments>http://tcsoftware.net/blog/2011/03/capturing-return-enter-in-datagridviewtextboxcells-in-a-datagridview/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 11:05:14 +0000</pubDate>
		<dc:creator>tc</dc:creator>
				<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://tcsoftware.net/blog/?p=19</guid>
		<description><![CDATA[By default the DataGridView will move to the cell below whenever the user presses the return key and the only way for a user to add a new line to a text box cell, if the column&#8217;s style WrapMode has &#8230; <a href="http://tcsoftware.net/blog/2011/03/capturing-return-enter-in-datagridviewtextboxcells-in-a-datagridview/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>By default the DataGridView will move to the cell below whenever the user presses the return key and the only way for a user to add a new line to a text box cell, if the column&#8217;s style WrapMode has been set to true, is to press SHIFT+ENTER.<br />
For many users editing a multiline field in a DataGridView this behaviour can be annoying and counter-intuitive but changing this behaviour is not just as simple as adding a KeyDown / KeyPress event handler.</p>
<p>To Change the default behaviour of the DataGridView&#8217;s response to the key press we must implement a new class which is derived from DataGridView and then override the ProcessCmdKey member, allowing us to intercept the message before the DataGridView applies its logic and apply our own.</p>
<p>For the application I am working I wanted a new line to be created when the user pressed the return key instead of moving to the next row if the user was editing a text box cell and the cell&#8217;s WrapMode was true. The following code is what we&#8217;re using at the moment in one of our applications:<br />
<span class="notranslate">
<pre>	<span style="color: #3366ff;">public class</span> <span style="color: #00ccff;">MultiLineDataGridView </span>: <span style="color: #00ccff;">DataGridView</span>
	{
		<span style="color: #3366ff;">protected override bool</span> ProcessCmdKey(<span style="color: #3366ff;">ref </span><span style="color: #00ccff;">Message </span>msg, <span style="color: #00ccff;">Keys </span>keyData)
		{
			<span style="color: #3366ff;">if </span>(<span style="color: #3366ff;">this</span>.CurrentCell is <span style="color: #00ccff;">DataGridViewTextBoxCell </span>&amp;&amp;
				<span style="color: #3366ff;">this</span>.CurrentCell.IsInEditMode &amp;&amp;
				(keyData == <span style="color: #00ccff;">Keys</span>.Enter || keyData == <span style="color: #00ccff;">Keys</span>.Return))
			{
				<span style="color: #00ccff;">SendKeys</span>.Send(<span style="color: #800000;">"+~"</span>);
				<span style="color: #3366ff;">return true</span>;
			}<span style="color: #3366ff;">else</span>
				<span style="color: #3366ff;">return base</span>.ProcessCmdKey(<span style="color: #3366ff;">ref </span>msg, keyData);
		}
	}</pre>
<p></span><br />
While I&#8217;m no fan of using SendKeys and would much rather modify the key code being processed by the application it turns out that in this case the DataGridView responds better to having the key event triggered as if the user had initiated it themselves and will create new lines in Word Wrapped text box cells but apply its default behaviour (and move to the next row) on any other cell.</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 58px; width: 1px; height: 1px; overflow: hidden;">
<p>intuitive</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://tcsoftware.net/blog/2011/03/capturing-return-enter-in-datagridviewtextboxcells-in-a-datagridview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Efficient Subtotalling in MySQL</title>
		<link>http://tcsoftware.net/blog/2011/01/efficient-subtotalling-in-mysql/</link>
		<comments>http://tcsoftware.net/blog/2011/01/efficient-subtotalling-in-mysql/#comments</comments>
		<pubDate>Mon, 10 Jan 2011 17:02:21 +0000</pubDate>
		<dc:creator>tc</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://tcsoftware.net/blog/?p=9</guid>
		<description><![CDATA[I quite often find when developing a site or an application that uses an SQL database that I have to produce multiple subtotals from a single table and/or using very complex rules and most of the time I&#8217;m trying to &#8230; <a href="http://tcsoftware.net/blog/2011/01/efficient-subtotalling-in-mysql/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I quite often find when developing a site or an application that uses an SQL database that I have to produce multiple subtotals from a single table and/or using very complex rules and most of the time I&#8217;m trying to generate these totals using SQL only to minimize the workload on a system. While there are many ways to do this by far the most efficient and flexible way I&#8217;ve found is to use the aggregate function SUM() and IF() in MySQL.</p>
<p>For example, recently while working on <a href="http://www.cararena.co.uk" target="_blank">Car Arena</a>, we needed to produce a report for the site owners which contained the number of trade cars, private cars and the total number of cars submitted per day. Not only was this report to be as lightweight as possible (as it would display all dates on a single page) but also writing a query which would produce the report without calculating the product of a conditional statement would possibly mean writing subqueries and overcomplicating the SQL.</p>
<p>So for this report my solution was to count the number of records in the database which had its trade valuation flag set to true and the total number of cars grouped into days, months and years. The conditional statement IF produces the value of 1 or 0, depending on the logic for the field, which is then passed to SUM to &#8216;count&#8217; the number of records in the group. For example:</p>
<blockquote><p>SUM(IF(TradeValuation, 1, 0)) As Trade</p></blockquote>
<p>While TRUE and FALSE can be cast to an unsigned integer type MySQL defines TRUE as being anything but zero. TRUE and FALSE are simply aliases for 1 and 0 respectively and while often you find zero and one being used as boolean values within a database using IF() ensures you never fall fowl of the exception to the rule and future proofs the statement somewhat.</p>
<p>The whole statement for this report which calculates the subtotals for the number of cars posted was just:</p>
<p style="text-align: center;"><a href="http://tcsoftware.net/blog/wp-content/uploads/2011/01/sql-sub-total.jpg"><img class="size-full wp-image-10 aligncenter" title="SQL for sub-totals on a car arena report" src="http://tcsoftware.net/blog/wp-content/uploads/2011/01/sql-sub-total.jpg" alt="" width="604" height="327" /></a></p>
<p>Just one pass on the Valuations table is needed to generate the subtotals for the report so responses are quick and do not require much of the web servers resources.</p>
]]></content:encoded>
			<wfw:commentRss>http://tcsoftware.net/blog/2011/01/efficient-subtotalling-in-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

