<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.2.2" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
	<title>Comments on: Advanced MySQL user variable techniques</title>
	<link>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/</link>
	<description>Stay curious!</description>
	<pubDate>Sun, 20 Jul 2008 22:46:06 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2.2</generator>

	<item>
		<title>By: Josh Strike</title>
		<link>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-14689</link>
		<author>Josh Strike</author>
		<pubDate>Tue, 03 Jun 2008 05:36:01 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-14689</guid>
		<description>Thanks. I tried that, actually...but something really bizarre seems to happen with the ORDER BY -- at least the way I'm running it. Say I'm ordering the example by type in a subquery; The results come out in the correct order, but @num is still being incremented according to the original order. I'm thinking maybe I need to somehow have those variables eval in the order clause rather than the where...if that's somehow possible...</description>
		<content:encoded><![CDATA[<p>Thanks. I tried that, actually&#8230;but something really bizarre seems to happen with the ORDER BY &#8212; at least the way I&#8217;m running it. Say I&#8217;m ordering the example by type in a subquery; The results come out in the correct order, but @num is still being incremented according to the original order. I&#8217;m thinking maybe I need to somehow have those variables eval in the order clause rather than the where&#8230;if that&#8217;s somehow possible&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Xaprb</title>
		<link>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-14688</link>
		<author>Xaprb</author>
		<pubDate>Tue, 03 Jun 2008 03:26:25 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-14688</guid>
		<description>You can do things in "derived tables" and order them inside that table; then join against the table you want to update.  MySQL will (probably, sometimes) put the derived table first in the join order.

To be clear:

update foo inner join (select .... [with variable magic] order by bar) as x using(somecol) set foo.y = x.z</description>
		<content:encoded><![CDATA[<p>You can do things in &#8220;derived tables&#8221; and order them inside that table; then join against the table you want to update.  MySQL will (probably, sometimes) put the derived table first in the join order.</p>
<p>To be clear:</p>
<p>update foo inner join (select &#8230;. [with variable magic] order by bar) as x using(somecol) set foo.y = x.z</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Josh Strike</title>
		<link>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-14687</link>
		<author>Josh Strike</author>
		<pubDate>Tue, 03 Jun 2008 03:00:43 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-14687</guid>
		<description>I should have said... can't order a multi-table update.
Actually, I'm still banging my head against that one...without which this method won't work...Any ideas for how to force order in that case so this could work?</description>
		<content:encoded><![CDATA[<p>I should have said&#8230; can&#8217;t order a multi-table update.<br />
Actually, I&#8217;m still banging my head against that one&#8230;without which this method won&#8217;t work&#8230;Any ideas for how to force order in that case so this could work?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Josh Strike</title>
		<link>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-14686</link>
		<author>Josh Strike</author>
		<pubDate>Tue, 03 Jun 2008 02:11:33 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-14686</guid>
		<description>First of all, brilliant; I don't know how you reached this hack but it's great. Now we can do a massive recursive update in one query instead of maybe a few hundred queries. AWESOME.

The biggest problem, of course, is the ordering thing, and the fact that you can't order an update query... so it has to be really carefully constructed.

I noticed too that there were some issues, at least in my implementation, where @type would be set at the same time as @num, which could result in some weird behaviour.

Rather than putting @type:=type IS NOT NULL in a separate where clause, doing this seems to help ensure the execution order:

select *, @num
from fruits
where
   (@num := if(type = @type, @num   1, IF(@type := type,1,1))) is not null
   and (@num </description>
		<content:encoded><![CDATA[<p>First of all, brilliant; I don&#8217;t know how you reached this hack but it&#8217;s great. Now we can do a massive recursive update in one query instead of maybe a few hundred queries. AWESOME.</p>
<p>The biggest problem, of course, is the ordering thing, and the fact that you can&#8217;t order an update query&#8230; so it has to be really carefully constructed.</p>
<p>I noticed too that there were some issues, at least in my implementation, where @type would be set at the same time as @num, which could result in some weird behaviour.</p>
<p>Rather than putting @type:=type IS NOT NULL in a separate where clause, doing this seems to help ensure the execution order:</p>
<p>select *, @num<br />
from fruits<br />
where<br />
   (@num := if(type = @type, @num   1, IF(@type := type,1,1))) is not null<br />
   and (@num</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Xaprb</title>
		<link>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-14459</link>
		<author>Xaprb</author>
		<pubDate>Sat, 19 Apr 2008 15:20:41 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-14459</guid>
		<description>Dan, yes we're depending on undocumented behavior.</description>
		<content:encoded><![CDATA[<p>Dan, yes we&#8217;re depending on undocumented behavior.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dan</title>
		<link>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-14458</link>
		<author>Dan</author>
		<pubDate>Sat, 19 Apr 2008 14:05:37 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-14458</guid>
		<description>Excellent investigative work, thank you.

One issue that concerns me is that within the call to GREATEST(), the order of evaluation of each argument is assumed to be left to right.  So that in

greatest(
   @num := if(@type = type, @num   1, 1),
   least(0, length(@type := type)))

The comparison @type = type is done before the new assignment, within length(), within least() of @type := type.  Without this order, this would not work.

I could not find anything in the mysql reference manual that confirms that function parameters are evaluated left to right.

Clearly this works, but are we depending on undocumented behaviour subject to change or have I missed something?

Thanks</description>
		<content:encoded><![CDATA[<p>Excellent investigative work, thank you.</p>
<p>One issue that concerns me is that within the call to GREATEST(), the order of evaluation of each argument is assumed to be left to right.  So that in</p>
<p>greatest(<br />
   @num := if(@type = type, @num   1, 1),<br />
   least(0, length(@type := type)))</p>
<p>The comparison @type = type is done before the new assignment, within length(), within least() of @type := type.  Without this order, this would not work.</p>
<p>I could not find anything in the mysql reference manual that confirms that function parameters are evaluated left to right.</p>
<p>Clearly this works, but are we depending on undocumented behaviour subject to change or have I missed something?</p>
<p>Thanks</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Xaprb</title>
		<link>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-13727</link>
		<author>Xaprb</author>
		<pubDate>Thu, 29 Nov 2007 11:44:46 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-13727</guid>
		<description>See http://dev.mysql.com/doc/en/user-variables.html</description>
		<content:encoded><![CDATA[<p>See <a href="http://dev.mysql.com/doc/en/user-variables.html" rel="nofollow">http://dev.mysql.com/doc/en/user-variables.html</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Nwfrg</title>
		<link>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-13725</link>
		<author>Nwfrg</author>
		<pubDate>Thu, 29 Nov 2007 04:55:24 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-13725</guid>
		<description>I looked around a bit and I can't find anything about the colon equals (:=) you use in your example.

What the difference between...

set @num := 0

    and

set @num = 0</description>
		<content:encoded><![CDATA[<p>I looked around a bit and I can&#8217;t find anything about the colon equals (:=) you use in your example.</p>
<p>What the difference between&#8230;</p>
<p>set @num := 0</p>
<p>    and</p>
<p>set @num = 0</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Web Developer Blog &#187; Blog Archive &#187; MySQL User Variables</title>
		<link>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-8287</link>
		<author>Web Developer Blog &#187; Blog Archive &#187; MySQL User Variables</author>
		<pubDate>Tue, 22 May 2007 20:42:52 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-8287</guid>
		<description>[...] http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/ [...]</description>
		<content:encoded><![CDATA[<p>[&#8230;] <a href="http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/" rel="nofollow">http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/</a> [&#8230;]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ernest Leitch</title>
		<link>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-6269</link>
		<author>Ernest Leitch</author>
		<pubDate>Fri, 04 May 2007 18:55:13 +0000</pubDate>
		<guid>http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/#comment-6269</guid>
		<description>&lt;p&gt;I found your site while looking for user type variables in HAVING statements because I had a problem trying to use them in a having statement.

It wasn't the silver bullet solution I was looking for, but it lead me to figure out where to put my variable evaluations so it would bring back the right values.

I'm glad you figured this out because I wouldn't have thought to hide the variables in and IS NOT NULL statement. I placed them in a LEFT JOIN and they started evaluation correctly and now it's the sweetest query I've ever written.&lt;/p&gt;</description>
		<content:encoded><![CDATA[<p>I found your site while looking for user type variables in HAVING statements because I had a problem trying to use them in a having statement.</p>
<p>It wasn&#8217;t the silver bullet solution I was looking for, but it lead me to figure out where to put my variable evaluations so it would bring back the right values.</p>
<p>I&#8217;m glad you figured this out because I wouldn&#8217;t have thought to hide the variables in and IS NOT NULL statement. I placed them in a LEFT JOIN and they started evaluation correctly and now it&#8217;s the sweetest query I&#8217;ve ever written.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
