{"id":2346,"date":"2014-09-16T14:48:47","date_gmt":"2014-09-16T14:48:47","guid":{"rendered":"http:\/\/www.sitekickr.com\/blog\/?p=2346"},"modified":"2014-09-16T15:31:20","modified_gmt":"2014-09-16T15:31:20","slug":"combining-multiple-sql-queries-listing-pages","status":"publish","type":"post","link":"https:\/\/www.sitekickr.com\/blog\/combining-multiple-sql-queries-listing-pages\/","title":{"rendered":"Combining multiple SQL queries for listing pages into one"},"content":{"rendered":"<p>Unfortunately, I&#8217;m often tasked with maintaining other peoples code. This isn&#8217;t always a bad thing though, as you can really learn from other peoples coding practices.<\/p>\n<p>Occasionally though, you see something that is elegant as far as code organization\/readability goes, but isn&#8217;t necessarily geared towards performance.<\/p>\n<p>In some extreme cases, I&#8217;ve seen code that is extremely inefficient. One such case is that of looping over database queries.<\/p>\n<p>This practice involves wrapping a query in a for loop, which changes one condition within the query with each iteration. I&#8217;ve seen this most commonly on listing pages.<\/p>\n<p>For example, if you were to create a product listing page with pricing, the inefficient &#8220;looped query&#8221; method would look something like this (using ColdFusion code for my examples):<\/p>\n<pre class=\"prettyprint\">&lt;cfloop list=\"#productList#\" index=\"product\"&gt;\r\n  &lt;cfquery name=\"modelQuery\"&gt;\r\n     SELECT code, price\r\n     FROM models\r\n     WHERE code = &lt;cfqueryparam value=\"#product#\"&gt;\r\n  &lt;\/cfquery&gt;\r\n\r\n  &lt;cfoutput&gt;#product#: #modelQuery.price#\r\n&lt;\/cfloop&gt;<\/pre>\n<p>Let&#8217;s think about this though. With each iteration, you are calling an external program (the database server) to make a request. Now consider that your database might be on another server and the inefficiency compounds.<\/p>\n<p>With a little extra effort, you can construct a single query that returns multiple rows using the SQL IN operator.<\/p>\n<p>From there, you can convert the query results into a language construct that is easy to work with. In ColdFusion, this would be a structure, in PHP, an associative array.<\/p>\n<pre class=\"prettyprint\">&lt;cfset allModels = \"prod1,prod2,prod3,prod4\"&gt;\r\n&lt;cfset modelCount = ListLen(allModels)&gt;\r\n\r\n&lt;cfquery name=\"modelsQuery\"&gt;\r\n  SELECT name, price\r\n  FROM models\r\n  WHERE code IN (\r\n    &lt;cfloop from=\"1\" to=\"#modelCount#\" index=\"i\"&gt;\r\n        &lt;cfqueryparam value=\"#ListGetAt(allModels, i)#\"&gt;\r\n        &lt;cfif i neq modelCount&gt;, &lt;\/cfif&gt;\r\n    &lt;\/cfloop&gt;)\r\n&lt;\/cfquery&gt;\r\n\r\n&lt;cfset modelStruct = StructNew()&gt;\r\n&lt;cfloop query=\"modelsQuery\"&gt;\r\n    &lt;cfset modelStruct[modelsQuery.code] = modelsQuery.price&gt;\r\n&lt;\/cfloop&gt;<\/pre>\n<p>A dump of the resulting structure might look like this:<\/p>\n<table>\n<tbody>\n<tr>\n<th title=\"click to collapse\" colspan=\"2\"><span style=\"font-weight: normal;\">struct<\/span><\/th>\n<\/tr>\n<tr>\n<td title=\"click to collapse\"><span style=\"font-size: 12px; line-height: 18px;\">prod1<\/span><\/td>\n<td><span style=\"font-size: 12px; line-height: 18px;\">19.95<\/span><\/td>\n<\/tr>\n<tr>\n<td title=\"click to collapse\"><span style=\"font-size: 12px; line-height: 18px;\">prod2<\/span><\/td>\n<td><span style=\"font-size: 12px; line-height: 18px;\">49.95<\/span><\/td>\n<\/tr>\n<tr>\n<td title=\"click to collapse\"><span style=\"font-size: 12px; line-height: 18px;\">prod3<\/span><\/td>\n<td><span style=\"font-size: 12px; line-height: 18px;\">49.95<\/span><\/td>\n<\/tr>\n<tr>\n<td title=\"click to collapse\"><span style=\"font-size: 12px; line-height: 18px;\">prod4<\/span><\/td>\n<td><span style=\"font-size: 12px; line-height: 18px;\">39.95<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>From here, you can simply loop over your list of products, and request a value from the structure with each iteration.<\/p>\n<pre class=\"prettyprint\">&lt;cfloop list=\"#productList#\" index=\"product\"&gt;\r\n  &lt;cfoutput&gt;#product#: #modelStruct[product]#\r\n&lt;\/cfloop&gt;<\/pre>\n<p>As you can see, the code is a little bit more lenghty, and perhaps less elegant. But, it saves multiple trips to the database, which will speed up your page load.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>With a little extra effort, you can construct a single query that returns multiple rows using the SQL IN operator.<br \/>\nFrom there, you can convert the query results into a language construct that is easy to work with. <\/p>\n","protected":false},"author":1,"featured_media":2349,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"amp_status":""},"categories":[13],"tags":[94,99,128,42],"_links":{"self":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/2346"}],"collection":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/comments?post=2346"}],"version-history":[{"count":4,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/2346\/revisions"}],"predecessor-version":[{"id":2351,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/2346\/revisions\/2351"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/media\/2349"}],"wp:attachment":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/media?parent=2346"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/categories?post=2346"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/tags?post=2346"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}