<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Wrong GROUP BY makes your queries fragile</title>
	<atom:link href="http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/</link>
	<description>Percona&#039;s MySQL &#38; InnoDB performance and scalability blog</description>
	<lastBuildDate>Sat, 11 Feb 2012 16:45:54 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
	<item>
		<title>By: marcus</title>
		<link>http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/comment-page-1/#comment-459800</link>
		<dc:creator>marcus</dc:creator>
		<pubDate>Fri, 30 Jan 2009 07:38:24 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/#comment-459800</guid>
		<description>
SELECT name, address, MAX(age) FROM t GROUP BY name;


isnt this sql statement wrong? if you are grouping by name, you get a subset of address and age. on age you are applying an aggregate operator (MAX), but which item of the subset is seleected from address?

if table name, address, age contains

meier, street a, 23
meier, street b, 26

the group-by  subset should be meier, (street a, street b), (23, 26)

max means 

meier, (???), 26

so i&#039;d expect sorta subset instead of questionmark. which aggregate operator is applied here? and, isnt it fatal for development to select apples and max(price) while grouping by peaches?

regards,
marcus</description>
		<content:encoded><![CDATA[<p>SELECT name, address, MAX(age) FROM t GROUP BY name;</p>
<p>isnt this sql statement wrong? if you are grouping by name, you get a subset of address and age. on age you are applying an aggregate operator (MAX), but which item of the subset is seleected from address?</p>
<p>if table name, address, age contains</p>
<p>meier, street a, 23<br />
meier, street b, 26</p>
<p>the group-by  subset should be meier, (street a, street b), (23, 26)</p>
<p>max means </p>
<p>meier, (???), 26</p>
<p>so i&#8217;d expect sorta subset instead of questionmark. which aggregate operator is applied here? and, isnt it fatal for development to select apples and max(price) while grouping by peaches?</p>
<p>regards,<br />
marcus</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: jawaharlal</title>
		<link>http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/comment-page-1/#comment-209455</link>
		<dc:creator>jawaharlal</dc:creator>
		<pubDate>Fri, 30 Nov 2007 09:02:39 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/#comment-209455</guid>
		<description>select sum of marks for all six columns and display the count more than one row.
my query is like following

select max(marks) from xyz where class=&#039;abc&#039; group by sname;</description>
		<content:encoded><![CDATA[<p>select sum of marks for all six columns and display the count more than one row.<br />
my query is like following</p>
<p>select max(marks) from xyz where class=&#8217;abc&#8217; group by sname;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: cemozdemir</title>
		<link>http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/comment-page-1/#comment-97408</link>
		<dc:creator>cemozdemir</dc:creator>
		<pubDate>Thu, 29 Mar 2007 09:26:19 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/#comment-97408</guid>
		<description>CREATE TABLE tblmakale (makaleid tinyint(3) unsigned NOT NULL default &#039;0&#039;,  uid tinyint(3) unsigned default &#039;0&#039;,  makaleicerik varchar(255) default NULL,  puan int(3) unsigned default NULL,  PRIMARY KEY  (makaleid),  KEY NewIndex (puan,makaleid,makaleicerik,uid)) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO tblmakale VALUES(&quot;3&quot;, &quot;2&quot;, &quot;gjgh&quot;, &quot;0&quot;);
INSERT INTO tblmakale VALUES(&quot;12&quot;, &quot;5&quot;, &quot;545645645&quot;, &quot;1&quot;);
INSERT INTO tblmakale VALUES(&quot;2&quot;, &quot;3&quot;, &quot;ghjghjghjghj&quot;, &quot;2&quot;);
INSERT INTO tblmakale VALUES(&quot;4&quot;, &quot;1&quot;, &quot;gg&quot;, &quot;3&quot;);
INSERT INTO tblmakale VALUES(&quot;9&quot;, &quot;7&quot;, &quot;thgjnm&quot;, &quot;4&quot;);
INSERT INTO tblmakale VALUES(&quot;0&quot;, &quot;2&quot;, &quot;fdsd&quot;, &quot;5&quot;);
INSERT INTO tblmakale VALUES(&quot;8&quot;, &quot;6&quot;, &quot;rtret&quot;, &quot;5&quot;);
INSERT INTO tblmakale VALUES(&quot;11&quot;, &quot;6&quot;, &quot;ghnb&quot;, &quot;6&quot;);
INSERT INTO tblmakale VALUES(&quot;10&quot;, &quot;5&quot;, &quot;ewrt65&quot;, &quot;7&quot;);
INSERT INTO tblmakale VALUES(&quot;1&quot;, &quot;5&quot;, &quot;fgjhgj&quot;, &quot;10&quot;);
INSERT INTO tblmakale VALUES(&quot;5&quot;, &quot;0&quot;, &quot;g&quot;, &quot;10&quot;);
INSERT INTO tblmakale VALUES(&quot;13&quot;, &quot;3&quot;, &quot;12323423&quot;, &quot;11&quot;);
INSERT INTO tblmakale VALUES(&quot;14&quot;, &quot;2&quot;, &quot;reggfjmnljÃ§pÄ±&quot;, &quot;12&quot;);
INSERT INTO tblmakale VALUES(&quot;16&quot;, &quot;0&quot;, &quot;iiiiiiiiiiiiii&quot;, &quot;18&quot;);
INSERT INTO tblmakale VALUES(&quot;6&quot;, &quot;0&quot;, &quot;hhh&quot;, &quot;20&quot;);
INSERT INTO tblmakale VALUES(&quot;15&quot;, &quot;2&quot;, &quot;ÅŸliÅŸlilÅŸilÅŸi&quot;, &quot;21&quot;);
INSERT INTO tblmakale VALUES(&quot;7&quot;, &quot;3&quot;, &quot;jkll&quot;, &quot;22&quot;);



select a.uid, a.makaleicerik, a.puan, a.makaleid from tblmakale a
inner join tblmakale b on a.uid = b.uid group by a.uid, a.makaleicerik, a.puan having a.puan = max(b.puan)</description>
		<content:encoded><![CDATA[<p>CREATE TABLE tblmakale (makaleid tinyint(3) unsigned NOT NULL default &#8217;0&#8242;,  uid tinyint(3) unsigned default &#8217;0&#8242;,  makaleicerik varchar(255) default NULL,  puan int(3) unsigned default NULL,  PRIMARY KEY  (makaleid),  KEY NewIndex (puan,makaleid,makaleicerik,uid)) ENGINE=MyISAM DEFAULT CHARSET=latin1;</p>
<p>INSERT INTO tblmakale VALUES(&#8220;3&#8243;, &#8220;2&#8243;, &#8220;gjgh&#8221;, &#8220;0&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;12&#8243;, &#8220;5&#8243;, &#8220;545645645&#8243;, &#8220;1&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;2&#8243;, &#8220;3&#8243;, &#8220;ghjghjghjghj&#8221;, &#8220;2&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;4&#8243;, &#8220;1&#8243;, &#8220;gg&#8221;, &#8220;3&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;9&#8243;, &#8220;7&#8243;, &#8220;thgjnm&#8221;, &#8220;4&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;0&#8243;, &#8220;2&#8243;, &#8220;fdsd&#8221;, &#8220;5&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;8&#8243;, &#8220;6&#8243;, &#8220;rtret&#8221;, &#8220;5&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;11&#8243;, &#8220;6&#8243;, &#8220;ghnb&#8221;, &#8220;6&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;10&#8243;, &#8220;5&#8243;, &#8220;ewrt65&#8243;, &#8220;7&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;1&#8243;, &#8220;5&#8243;, &#8220;fgjhgj&#8221;, &#8220;10&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;5&#8243;, &#8220;0&#8243;, &#8220;g&#8221;, &#8220;10&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;13&#8243;, &#8220;3&#8243;, &#8220;12323423&#8243;, &#8220;11&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;14&#8243;, &#8220;2&#8243;, &#8220;reggfjmnljÃ§pÄ±&#8221;, &#8220;12&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;16&#8243;, &#8220;0&#8243;, &#8220;iiiiiiiiiiiiii&#8221;, &#8220;18&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;6&#8243;, &#8220;0&#8243;, &#8220;hhh&#8221;, &#8220;20&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;15&#8243;, &#8220;2&#8243;, &#8220;ÅŸliÅŸlilÅŸilÅŸi&#8221;, &#8220;21&#8243;);<br />
INSERT INTO tblmakale VALUES(&#8220;7&#8243;, &#8220;3&#8243;, &#8220;jkll&#8221;, &#8220;22&#8243;);</p>
<p>select a.uid, a.makaleicerik, a.puan, a.makaleid from tblmakale a<br />
inner join tblmakale b on a.uid = b.uid group by a.uid, a.makaleicerik, a.puan having a.puan = max(b.puan)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: peter</title>
		<link>http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/comment-page-1/#comment-2313</link>
		<dc:creator>peter</dc:creator>
		<pubDate>Thu, 07 Sep 2006 09:22:28 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/#comment-2313</guid>
		<description>Sheeri, 

In my example I&#039;m saying login and id  have one to one relationship in schema.  But they are not unique in this example - This is &quot;log&quot; table  which for example logs all accesses by users including their id and login. 

I also do not understand you further comment - I specially show this as a case when columns can be accessed in group by even though they are not being grouped by.  

Really it does not have to be one to one relationship, it is enough to have same value for particular value of the column in group by.  For example  if we have City and County and  each City corresponds to only one County we could have something like:

SELECT county,city, avg(age) FROM people GROUP BY city; 

Not correct according to the standard but should not be fragile as there is only one county per city so it does not matter which one will be picked.</description>
		<content:encoded><![CDATA[<p>Sheeri, </p>
<p>In my example I&#8217;m saying login and id  have one to one relationship in schema.  But they are not unique in this example &#8211; This is &#8220;log&#8221; table  which for example logs all accesses by users including their id and login. </p>
<p>I also do not understand you further comment &#8211; I specially show this as a case when columns can be accessed in group by even though they are not being grouped by.  </p>
<p>Really it does not have to be one to one relationship, it is enough to have same value for particular value of the column in group by.  For example  if we have City and County and  each City corresponds to only one County we could have something like:</p>
<p>SELECT county,city, avg(age) FROM people GROUP BY city; </p>
<p>Not correct according to the standard but should not be fragile as there is only one county per city so it does not matter which one will be picked.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sheeri</title>
		<link>http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/comment-page-1/#comment-2299</link>
		<dc:creator>Sheeri</dc:creator>
		<pubDate>Thu, 07 Sep 2006 00:19:23 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/#comment-2299</guid>
		<description>&lt;I&gt;especially if GROUP BY is executed via sorting.&lt;/I&gt;

Um, in your example, you say that id and login are unique -- I&#039;m assuming that&#039;s enforced with UNIQUE KEY, right?  The internals manual states that GROUP BY uses sorting when there is no index.....so while you are correct in the general case, that GROUP BY may be faster if it does not have to sort, your example does not fit your point.

The query in your example is a bad one, but not because of the optimizer&#039;s behavior.  The query is poor (and I&#039;m sure it&#039;s straight from clients who need your help!) because you do not NEED to GROUP BY 2 elements if they have a 1:1 relationship.  Folks need to pick one element in that case.  I&#039;m sure other DBMS&#039; don&#039;t handle this case &quot;right&quot; either.

This can be summed up with a &quot;Best practice&quot; -- &quot;Do not GROUP BY more than you need to.&quot;  

see
http://dev.mysql.com/doc/internals/en/optimizer.html
under &quot;GROUP BY&quot;</description>
		<content:encoded><![CDATA[<p><i>especially if GROUP BY is executed via sorting.</i></p>
<p>Um, in your example, you say that id and login are unique &#8212; I&#8217;m assuming that&#8217;s enforced with UNIQUE KEY, right?  The internals manual states that GROUP BY uses sorting when there is no index&#8230;..so while you are correct in the general case, that GROUP BY may be faster if it does not have to sort, your example does not fit your point.</p>
<p>The query in your example is a bad one, but not because of the optimizer&#8217;s behavior.  The query is poor (and I&#8217;m sure it&#8217;s straight from clients who need your help!) because you do not NEED to GROUP BY 2 elements if they have a 1:1 relationship.  Folks need to pick one element in that case.  I&#8217;m sure other DBMS&#8217; don&#8217;t handle this case &#8220;right&#8221; either.</p>
<p>This can be summed up with a &#8220;Best practice&#8221; &#8212; &#8220;Do not GROUP BY more than you need to.&#8221;  </p>
<p>see<br />
<a href="http://dev.mysql.com/doc/internals/en/optimizer.html" rel="nofollow">http://dev.mysql.com/doc/internals/en/optimizer.html</a><br />
under &#8220;GROUP BY&#8221;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Lukas</title>
		<link>http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/comment-page-1/#comment-2296</link>
		<dc:creator>Lukas</dc:creator>
		<pubDate>Wed, 06 Sep 2006 21:43:22 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/#comment-2296</guid>
		<description>I recommend people enable the sql mode to prevent these kinds of queries:

#

ONLY_FULL_GROUP_BY

Do not allow queries for which the SELECT list refers to non-aggregated columns that are not named in the GROUP BY clause. The following query is invalid with this mode enabled because address is not named in the GROUP BY clause:

SELECT name, address, MAX(age) FROM t GROUP BY name;

As of MySQL 5.0.23, this mode also restricts references to non-aggregated columns in the HAVING clause that are not named in the GROUP BY clause.</description>
		<content:encoded><![CDATA[<p>I recommend people enable the sql mode to prevent these kinds of queries:</p>
<p>#</p>
<p>ONLY_FULL_GROUP_BY</p>
<p>Do not allow queries for which the SELECT list refers to non-aggregated columns that are not named in the GROUP BY clause. The following query is invalid with this mode enabled because address is not named in the GROUP BY clause:</p>
<p>SELECT name, address, MAX(age) FROM t GROUP BY name;</p>
<p>As of MySQL 5.0.23, this mode also restricts references to non-aggregated columns in the HAVING clause that are not named in the GROUP BY clause.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: PesAfTeftReem</title>
		<link>http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/comment-page-1/#comment-805875</link>
		<dc:creator>PesAfTeftReem</dc:creator>
		<pubDate>Wed, 06 Sep 2006 07:00:01 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/#comment-805875</guid>
		<description>&lt;div class=&quot;item-body&quot;&gt;&lt;p&gt;Bloomberg Drug News  &lt;a href=&quot;http://www.kindercareschool.com/&quot; rel=&quot;nofollow&quot;&gt;anxiety medication buspar&lt;/a&gt;  BuSpar is available as tablets for oral administration containing 5 mg, 10 mg, 15 mg, or 30 mg of buspirone hydrochloride.  &lt;a href=&quot;http://www.kindercareschool.com/&quot; rel=&quot;nofollow&quot;&gt;http://www.kindercareschool.com/&lt;/a&gt; &#8211; buy buspar online&lt;/p&gt;
&lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;
</description>
		<content:encoded><![CDATA[<div class="item-body">
<p>Bloomberg Drug News  <a href="http://www.kindercareschool.com/" rel="nofollow">anxiety medication buspar</a>  BuSpar is available as tablets for oral administration containing 5 mg, 10 mg, 15 mg, or 30 mg of buspirone hydrochloride.  <a href="http://www.kindercareschool.com/" rel="nofollow">http://www.kindercareschool.com/</a> &ndash; buy buspar online</p>
<div class="clear"></div>
</div>
]]></content:encoded>
	</item>
</channel>
</rss>

