<?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>alanjames.org &#187; mysql</title>
	<atom:link href="http://www.alanjames.org/tag/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.alanjames.org</link>
	<description>Things I thought worth sharing.</description>
	<lastBuildDate>Sun, 11 Jul 2010 11:09:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Within-group aggregates with another wrinkle.</title>
		<link>http://www.alanjames.org/2010/02/within-group-aggregates-with-another-wrinkle/</link>
		<comments>http://www.alanjames.org/2010/02/within-group-aggregates-with-another-wrinkle/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 15:31:47 +0000</pubDate>
		<dc:creator>Alan</dc:creator>
				<category><![CDATA[Geekery]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.alanjames.org/?p=157</guid>
		<description><![CDATA[Recently when optimising an SQL query I needed to return a specific subset of records from a large table. The brilliant Common Queries Tree pointed me in the right direction, but the examples didn&#8217;t quite cover my specific case. I &#8230; <a href="http://www.alanjames.org/2010/02/within-group-aggregates-with-another-wrinkle/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Recently when optimising an SQL query I needed to return a specific subset of records from a large table. The brilliant <a href="http://www.artfulsoftware.com/infotree/queries.php?&#038;bw=1165">Common Queries Tree</a> pointed me in the right direction, but the examples didn&#8217;t quite cover my specific case.</p>
<p>I needed the records with the maximal value of x and the minimal value of y for that x.</p>
<p>For example, suppose you had a table of second hand books and each book has a quality and price. There are many copies of each book but you&#8217;re only interested in the best examples of each book and at the lowest price for that quality.</p>
<p><code><br />
CREATE TABLE Books( id int,<br />
                                     ISBN varchar(10),<br />
                                     Quality int,<br />
                                     price decimal(6,2)<br />
                                   );<br />
INSERT INTO Books VALUES<br />
( 1, '0618551050', 4, 5.00 ),<br />
( 2, '0618551050', 4, 6.00 ),<br />
( 3, '0618551050', 2, 3.00 ),<br />
( 4, '0786884061', 1, 8.00 ),<br />
( 5, '0786884061', 3, 8.00 );<br />
</code></p>
<p>Here we are only interested in records 1 and 5. The Common Queries Tree describes this as a <a href="http://www.artfulsoftware.com/infotree/queries.php?&#038;bw=1165#101">within-group aggregates</a> problem, and as it notes the <em>correlated subquery</em> is the most obvious solution but it was slow.</p>
<p>I started off with something like this<br />
<code>Select * from Books as b1<br />
where b1.id = (SELECT id from Books where Books.ISBN = b1.ISBN order by Quality desc, Price limit 1);</code></p>
<p>But with almost a million records in the table, a select on each one was taking forever. After a bit of head scratching I managed to use a <em>left self exclusion join</em> to find the records I wanted.</p>
<p><code>select b1.* from Books as b1<br />
left join Books as b2 on b1.ISBN = b2.ISBN and b1.Quality < b2.Quality<br />
left join Books as b3 on b1.ISBN = b3.ISBN and b1.Quality = b3.Quality and b1.Price > b3.Price<br />
WHERE b2.id is NULL and b3.id is NULL;</code></p>
<p>Here the idea is to select as b1 the records from Books where its impossible to find a book, b2, that has a higher quality and impossible to find a book, b3 with the same quality as b1 but a lower price. If there was another book with a higher quality then b2.id would not be NULL  so those records are excluded. Similarly if a book at the same quality had been found but with a lower price, b3.id would not be null.</p>
<p>This was much faster on my data set but it does produce a slightly different result when two items are indistinguishable.<br />
<code>insert into Books VALUES ( 6, '0786884061', 3, 8.00 );</code></p>
<p>With that my initial query would return either record 5 or 6 and the new query returns both. So group by b1.ISBN to restore the old behaviour. Once you&#8217;re happy, save your query into a view so you don&#8217;t have to look at it again.</p>
<p>Got a better solution ? If you can optimise my view you&#8217;ll make me very happy.</p>
<p>Alan.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alanjames.org/2010/02/within-group-aggregates-with-another-wrinkle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL: Row N was truncated; a solution</title>
		<link>http://www.alanjames.org/2009/08/mysql-row-n-was-truncated-a-solution/</link>
		<comments>http://www.alanjames.org/2009/08/mysql-row-n-was-truncated-a-solution/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 15:56:38 +0000</pubDate>
		<dc:creator>Alan</dc:creator>
				<category><![CDATA[Geekery]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.alanjames.org/?p=128</guid>
		<description><![CDATA[You&#8217;re importing some data into MySQL and using LOAD DATA INFILE so you can do a SHOW WARNINGS afterwards. Every line of your import file has a warning: &#124; Warning &#124; 1262 &#124; Row 1 was truncated; it contained more &#8230; <a href="http://www.alanjames.org/2009/08/mysql-row-n-was-truncated-a-solution/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>You&#8217;re importing some data into MySQL and using LOAD DATA INFILE so you can do a SHOW WARNINGS afterwards. Every line of your import file has a warning:</p>
<p>| Warning | 1262 | Row 1 was truncated; it contained more data than there were input columns<br />
| Warning | 1262 | Row 2 was truncated; it contained more data than there were input columns<br />
&#8230;etc.</p>
<p>The fix is easy, and you&#8217;d think of it eventually, but you thought you&#8217;d try google instead. So I&#8217;m posting this so that when you do there is something to find. There wasn&#8217;t much when I looked.</p>
<p>It&#8217;s the line endings. MySQL isn&#8217;t getting what it expects, so specify the format of the file using LINES TERMINATED BY &#8216;\r\n&#8217; or whatever is appropriate for you:</p>
<p>&#8216;\r\n&#8217; for files that came from Windows systems<br />
&#8216;\r&#8217; for files from VMS<br />
&#8216;\n&#8217; for every other source.</p>
<p>Hope that helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alanjames.org/2009/08/mysql-row-n-was-truncated-a-solution/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
