{"id":2401,"date":"2011-01-27T10:30:24","date_gmt":"2011-01-27T08:30:24","guid":{"rendered":"http:\/\/code.openark.org\/blog\/?p=2401"},"modified":"2011-01-27T10:30:24","modified_gmt":"2011-01-27T08:30:24","slug":"multi-condition-update-query","status":"publish","type":"post","link":"https:\/\/code.openark.org\/blog\/mysql\/multi-condition-update-query","title":{"rendered":"Multi condition UPDATE query"},"content":{"rendered":"<p>A simple question I&#8217;ve been asked:<\/p>\n<p>Is it possible to merge two <strong>UPDATE<\/strong> queries, each on different <strong>WHERE<\/strong> conditions, into a single query?<\/p>\n<p>For example, is it possible to merge the following two <strong>UPDATE<\/strong> statements into one?<\/p>\n<blockquote>\n<pre>mysql&gt; <strong>UPDATE<\/strong> film <strong>SET<\/strong> rental_duration=rental_duration+1 <strong>WHERE<\/strong> rating = 'G';\r\nQuery OK, 178 rows affected (0.01 sec)\r\n\r\nmysql&gt; <strong>UPDATE<\/strong> film <strong>SET<\/strong> rental_rate=rental_rate-0.5 <strong>WHERE<\/strong> length &lt; 90;\r\nQuery OK, 320 rows affected (0.01 sec)\r\n<\/pre>\n<\/blockquote>\n<p>To verify our tests, we take a checksum:<\/p>\n<blockquote>\n<pre>mysql&gt; pager md5sum\r\nPAGER set to 'md5sum'\r\nmysql&gt; <strong>SELECT<\/strong> film_id, title, rental_duration, rental_rate <strong>FROM<\/strong> film <strong>ORDER BY<\/strong> film_id;\r\nc2d253c3919efaa6d11487b1fd5061f3\u00a0 -\r\n<\/pre>\n<\/blockquote>\n<p>Obviously, the following query is <strong>incorrect<\/strong>:<!--more--><\/p>\n<blockquote>\n<pre>mysql&gt; <strong>UPDATE<\/strong> film <strong>SET<\/strong> rental_duration=rental_duration+1, rental_rate=rental_rate-0.5\u00a0 <strong>WHERE<\/strong> rating = 'G' <strong>OR<\/strong> length &lt; 90;\r\nQuery OK, 431 rows affected (0.03 sec)\r\n\r\nmysql&gt; pager md5sum\r\nPAGER set to 'md5sum'\r\nmysql&gt; <strong>SELECT<\/strong> film_id, title, rental_duration, rental_rate <strong>FROM<\/strong> film <strong>ORDER BY<\/strong> film_id;\r\n09d450806e2cd7fa78a83ac5bef72d2b\u00a0 -\r\n<\/pre>\n<\/blockquote>\n<h4>Motivation<\/h4>\n<p>Why would you want to do that?<\/p>\n<ul>\n<li>While it may seem strange, the merge can be logically (application-wise) perfectly reasonable.<\/li>\n<li>The <strong>UPDATE<\/strong> may be time consuming &#8211; perhaps it requires full table scan on a large table. Doing it with one scan is faster than two scans.<\/li>\n<\/ul>\n<h4>The solution<\/h4>\n<p>Use a condition for the <strong>SET<\/strong> clauses, optionally drop the <strong>WHERE<\/strong> conditions.<\/p>\n<blockquote>\n<pre><strong>UPDATE<\/strong>\r\n film\r\n<strong>SET<\/strong>\r\n rental_duration=<strong>IF<\/strong>(rating = 'G', rental_duration+1, rental_duration),\r\n rental_rate=<strong>IF<\/strong>(length &lt; 90, rental_rate-0.5, rental_rate)\r\n;\r\n\r\nmysql&gt; pager md5sum\r\nPAGER set to 'md5sum'\r\nmysql&gt; <strong>SELECT<\/strong> film_id, title, rental_duration, rental_rate <strong>FROM<\/strong> film <strong>ORDER BY<\/strong> film_id;\r\nc2d253c3919efaa6d11487b1fd5061f3\u00a0 -\r\n<\/pre>\n<\/blockquote>\n<p>The above query necessarily does a full table scan. If there&#8217;s a benefit to using indexes in the <strong>WHERE<\/strong> clause, it may still be applied, using an <strong>OR<\/strong> condition:<\/p>\n<blockquote>\n<pre><strong>UPDATE<\/strong>\r\n film\r\n<strong>SET<\/strong>\r\n rental_duration=<strong>IF<\/strong>(rating = 'G', rental_duration+1, rental_duration),\r\n rental_rate=<strong>IF<\/strong>(length &lt; 90, rental_rate-0.5, rental_rate)\r\n<strong>WHERE<\/strong>\r\n rating = 'G'\r\n OR length &lt; 90\r\n;\r\n<\/pre>\n<\/blockquote>\n<p>If there is a computational overhead to the <strong>IF<\/strong> statement, I have not noticed it. This kind of solution plays well when each of the distinct queries requires a full scan, on large tables.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A simple question I&#8217;ve been asked: Is it possible to merge two UPDATE queries, each on different WHERE conditions, into a single query? For example, is it possible to merge the following two UPDATE statements into one? mysql&gt; UPDATE film SET rental_duration=rental_duration+1 WHERE rating = &#8216;G&#8217;; Query OK, 178 rows affected (0.01 sec) mysql&gt; UPDATE [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"enabled":false},"version":2}},"categories":[5],"tags":[26,21],"class_list":["post-2401","post","type-post","status-publish","format-standard","hentry","category-mysql","tag-indexing","tag-sql"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2bZZp-CJ","_links":{"self":[{"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/posts\/2401","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/comments?post=2401"}],"version-history":[{"count":33,"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/posts\/2401\/revisions"}],"predecessor-version":[{"id":3261,"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/posts\/2401\/revisions\/3261"}],"wp:attachment":[{"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/media?parent=2401"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/categories?post=2401"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/code.openark.org\/blog\/wp-json\/wp\/v2\/tags?post=2401"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}