{"id":138,"date":"2010-04-02T12:45:44","date_gmt":"2010-04-02T11:45:44","guid":{"rendered":"http:\/\/www.cotsweb.com\/blog\/?p=138"},"modified":"2010-04-02T12:45:44","modified_gmt":"2010-04-02T11:45:44","slug":"changing-the-sort-order-in-mysql-to-give-a-rolling-month","status":"publish","type":"post","link":"https:\/\/www.cotsweb.com\/blog\/changing-the-sort-order-in-mysql-to-give-a-rolling-month-138.html","title":{"rendered":"Changing the sort order in mySQL to give a rolling month"},"content":{"rendered":"<p>I have been working on a new website for <a title=\"Sophie's home-baked delights in Bourton on the Water\" href=\"http:\/\/www.sophiesbakeddelights.co.uk\" target=\"_blank\">Sophie&#8217;s Baked Delights of Bourton-on-the-Water<\/a>, Sophie creates the yummiest home-baked cakes (a sample was one of the perks of this particular job) and wanted a website to market her delicious wares.<\/p>\n<p>One of the pages displays the monthly menu for Sophie&#8217;s Baked Delights Club, a cake club where subscribers get a different home-baked cake delivered to them once per month.\u00a0 Each month subscribers can choose from\u00a0 two different cakes made with seasonal ingredients. Quite simple really but we wanted the page to display the menu in monthly order with the current month at the top.<\/p>\n<p>The cake details are stored in a mySQL database so Sophie can go in and change them as she changes her menu.\u00a0 But we only store the month rather than the full date so that the menu can just roll over from year to year without unneccesary maintenance being required.\u00a0\u00a0\u00a0 This meant that we couldn&#8217;t just read through the file by date nor (except in January) could we just read the months in their normal (Jan, Feb, Mar&#8230;) order, if the current month is April we want to display the months as Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec, Jan, Feb, Mar (stored as 4,5,6,7,8,9,10,11,12,1,2,3).<\/p>\n<h3>Specifying a sort sequence in mySQL<\/h3>\n<p>Fortunately mySQL has a mechanism for doing this, you can use ORDER BY FIELD in your select statement to specify the order you require.\u00a0 So the code we need is;<br \/>\n<pre class=\"preserve-code-formatting\">SELECT * FROM cake_club_menu ORDER BY FIELD(menu_month,4,5,6,7,8,9,10,11,12,1,2,3) , menu_sequence_nbr\n<\/pre><br \/>\nThis selects the records we want and sorts them on the field menu_month but in the sequence specified.\u00a0 The menu_sequence_nbr is a secondary sort field because we have 2 cakes per month and need to keep them in the right column.<\/p>\n<h3>Using PHP to Create the ORDER BY FIELD statement<\/h3>\n<p>Of course we can&#8217;t hard code the ORDER BY FIELD statement as the sequence will change every month, so I created a PHP function to create the\u00a0 statement, hopefully the following code is pretty clear<br \/>\n<pre class=\"preserve-code-formatting\">&amp;lt;?php\n\/\/\n\/\/ PHP functions for Sophies Baked Delights\n\/\/\nfunction orderByFieldText()\n{\n\/\/\n\/\/ Dynamically create text for Order By Field mySQL statement\n\/\/\u00a0\u00a0 This allows us to list items in month order with the current month first and rolling in to next year\n\/\/\n\/\/\u00a0 First get the current month\n\/\/\n$thisMonth =(date(&quot;n&quot;));\n\/\/\n\/\/\u00a0 Now set the base text for the statement - menu_month is the database field we want to order by\n\/\/\n$orderByField = &quot;ORDER BY FIELD(menu_month,&quot;;\n\/\/\n\/\/ Now loop through 12 times to create the list of month numbers for the statement\n\/\/\nfor ($i = 1; $i &amp;lt;= 12; $i +=1 )\n {\n $orderByField .= $thisMonth;\u00a0\u00a0 \/\/ Add this month to the statement\n if ($i &amp;lt;&amp;gt; 12) {\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ If this isn&#039;t the last item in the list insert a comma\n $orderByField .= &#039;,&#039;;\n }\n else {\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Else insert a closing bracket\n $orderByField .= &#039;)&#039;;\n }\n if ($thisMonth == 12)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ If we have got to December (12) next month is January (1)\n {\n $thisMonth = 1;\n }\n else {\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/\u00a0 Else next month is this month +1\n $thisMonth += 1;\n }\n }\nreturn $orderByField;\n}\n?&amp;gt;\n<\/pre><\/p>\n<h3>Reading the database and displaying the menu<\/h3>\n<p>Then we just need to call the function in the main PHP module and loop through the returned menu records writing the data to the screen as we go. \u00a0 As you can see from the following code I used a table with a row for each month.<br \/>\n<pre class=\"preserve-code-formatting\">&amp;lt;table id=&quot;cakeClubMenu&quot;&amp;gt;\n &amp;lt;tbody&amp;gt;\n&amp;lt;?php\n\/\/\n\/\/ Populate the order by field for the database lookup\n\/\/\n$orderByField = orderByFieldText();\n\/\/\n\/\/ Read the cake club menu file to populate the table\n\/\/\n$sql = &quot;SELECT * FROM cake_club_menu &quot; . $orderByField .&quot; , menu_sequence_nbr&quot;;\n$menu_array = mysql_query($sql);\n$i = 0;\n\/\/\n\/\/ Now write each line of the table in turn\n\/\/\nwhile($menu = mysql_fetch_array($menu_array)) {\n \/\/ convert month number to month name for display - thanks to &lt;a title=&quot;An easy way to convert a month number to a month name in PHP&quot; href=&quot;http:\/\/www.gilbertpellegrom.co.uk\/php-month-number-to-month-name-the-easy-way\/&quot;&gt;www.gilbertpellegrom.co.uk&lt;\/a&gt;\n $monthNum = $menu[&#039;menu_month&#039;];\u00a0 \u00a0\n $monthName = date(&quot;F&quot;, mktime(0, 0, 0, $monthNum, 10));\n\/\/\n\/\/\n switch ($menu[&#039;menu_sequence_nbr&#039;])\n {\n case 1 :\u00a0 \/\/ 1st cake for the month starts the row\n echo(&quot;&amp;lt;tr&amp;gt;\\n&quot;);\n echo(&#039;&amp;lt;td&amp;gt;&#039;.$monthName.&#039;&amp;lt;\/td&amp;gt;&#039;.&quot;\\n&quot;);\n echo(&#039;&amp;lt;td&amp;gt;&amp;lt;strong&amp;gt;&#039;.$menu[&#039;menu_cake_name&#039;].&#039;&amp;lt;\/strong&amp;gt; - &#039;.$menu[&#039;menu_cake_description&#039;].&#039;&amp;lt;\/td&amp;gt;&#039;.&quot;\\n&quot;);\n break;\n case 2 :\u00a0 \/\/ 2nd cake finishes the row\n echo(&#039;&amp;lt;td&amp;gt;OR&amp;lt;\/td&amp;gt;&#039;.&quot;\\n&quot;);\n echo(&#039;&amp;lt;td&amp;gt;&amp;lt;strong&amp;gt;&#039;.$menu[&#039;menu_cake_name&#039;].&#039;&amp;lt;\/strong&amp;gt; - &#039;.$menu[&#039;menu_cake_description&#039;].&#039;&amp;lt;\/td&amp;gt;&#039;.&quot;\\n&quot;);\n echo(&#039;&amp;lt;\/tr&amp;gt;&#039;.&quot;\\n&quot;);\n break;\n default : \/\/ If a 3rd cake is required then this will need modification - currently not allowed\n break;\n }\n }\necho(&#039;&amp;lt;\/tbody&amp;gt;&#039;.&quot;\\n&quot;);\necho(&#039;&amp;lt;\/table&amp;gt;&#039;.&quot;\\n&quot;);\n?&amp;gt;\n<\/pre><br \/>\nYou can see the finished product on the <a title=\"Sophie's Baked Delights club listing the menu on a rolling month basis\" href=\"http:\/\/www.sophiesbakeddelights.co.uk\/baked_delights_club_menu.php\">Sophie&#8217;s Baked Delights website<\/a>, and I can assure you that the cakes are very good indeed.<\/p>\n<p>Hopefully someone will find this method useful.\u00a0 As with most problems the answers are all on the internet, but sometimes you need to find the answer before you know what you should have been searching for.<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>I have been working on a new website for Sophie&#8217;s Baked Delights of Bourton-on-the-Water, Sophie creates the yummiest home-baked cakes (a sample was one of the perks of this particular job) and wanted a website to market her delicious wares. One of the pages displays the monthly menu for Sophie&#8217;s Baked Delights Club, a cake [&hellip;]<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[20,90,19,18],"tags":[146,145,91,93,92],"_links":{"self":[{"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/posts\/138"}],"collection":[{"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/comments?post=138"}],"version-history":[{"count":7,"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/posts\/138\/revisions"}],"predecessor-version":[{"id":145,"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/posts\/138\/revisions\/145"}],"wp:attachment":[{"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/media?parent=138"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/categories?post=138"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/tags?post=138"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}