<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Steve Sohcot</title>
    <description>The latest articles on Forem by Steve Sohcot (@stevesohcot).</description>
    <link>https://forem.com/stevesohcot</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F855611%2F24c62032-ff22-4be2-8ae0-08455458d3c9.jpeg</url>
      <title>Forem: Steve Sohcot</title>
      <link>https://forem.com/stevesohcot</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/stevesohcot"/>
    <language>en</language>
    <item>
      <title>SQL Server Loop Example</title>
      <dc:creator>Steve Sohcot</dc:creator>
      <pubDate>Fri, 18 Nov 2022 17:33:35 +0000</pubDate>
      <link>https://forem.com/stevesohcot/sql-server-loop-example-51k3</link>
      <guid>https://forem.com/stevesohcot/sql-server-loop-example-51k3</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jyVxR7db--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jf9ajckx7bgcn3o7dy96.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jyVxR7db--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jf9ajckx7bgcn3o7dy96.png" alt="SQL Loop Code" width="417" height="198"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I needed to run a LOOP statement in SQL. Normally I would do this with website server-side code (ex. PHP or Node.js), however this was needed for data analysis that I otherwise didn’t have a need for writing web-based code.&lt;/p&gt;

&lt;p&gt;I needed a solution compatible with MS SQL Server Management Studio ("SSMS").&lt;/p&gt;

&lt;h2&gt;
  
  
  Why even do this?
&lt;/h2&gt;

&lt;p&gt;I had a database table with millions of rows and I needed to create a table with a subset of this data.&lt;/p&gt;

&lt;p&gt;To create the table, I needed to run several INSERT queries; each having only slightly different WHERE criteria.&lt;/p&gt;

&lt;p&gt;By using a LOOP, I could dynamically create the table- and have a repeatable process as it would have to be done often.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to write a loop using SQL
&lt;/h2&gt;

&lt;p&gt;Here’s the code, explanation is below.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Let’s start with some fake data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rows 1–5 create a temporary table&lt;/li&gt;
&lt;li&gt;Rows 7–13 populate this table with data&lt;/li&gt;
&lt;li&gt;The value passed into my WHERE criteria (in my eventual INSERT statement) would be dynamically changing as it loops. The value will be stored in a variable called theOrg, declared on line 17.&lt;/li&gt;
&lt;li&gt;I’ll need to loop through a finite number of rows: starting at “1” (Row 18), and up through the number of rows in my temporary table (Row 19)&lt;/li&gt;
&lt;li&gt;Rows 21–29 is the actual loop:&lt;/li&gt;
&lt;li&gt;Row 24 gets the specific value that I’ll ultimately be querying on, based on a SELECT query using the variable cursorId&lt;/li&gt;
&lt;li&gt;Row 25 is where I could run an INSERT statement to generate the table, although here I’m using a SELECT statement for demonstration purposes&lt;/li&gt;
&lt;li&gt;Row 27 increments the variable cursorId so that the loop will continue&lt;/li&gt;
&lt;li&gt;Running it in SSMS, you’ll see this:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FO8Xrlyl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/303nwnfit0ia2pmml7vn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FO8Xrlyl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/303nwnfit0ia2pmml7vn.png" alt="SSMS Output of SQL Loop" width="219" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, now I can swap out the SELECT statement (Row 25) and use my real query (with an INSERT statement) to generate my dataset.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>sqlserver</category>
      <category>data</category>
      <category>database</category>
    </item>
    <item>
      <title>MS Access Slow Linking Between ODBC and Local Tables? Then Don’t Do It.</title>
      <dc:creator>Steve Sohcot</dc:creator>
      <pubDate>Fri, 04 Nov 2022 04:00:00 +0000</pubDate>
      <link>https://forem.com/stevesohcot/ms-access-slow-linking-between-odbc-and-local-tables-then-dont-do-it-ae5</link>
      <guid>https://forem.com/stevesohcot/ms-access-slow-linking-between-odbc-and-local-tables-then-dont-do-it-ae5</guid>
      <description>&lt;p&gt;Often when analyzing data from a SQL Server table via MS Access, I’ll create a local table to specify the values to query. I’ll then link the local table to the SQL Server table (via INNER JOIN).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9XK7TpKB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3jlcqj444jcz0rcat9ys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9XK7TpKB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3jlcqj444jcz0rcat9ys.png" alt="MS Access linking Local and Remote tables" width="611" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve noticed, at least in recent versions of MS Access, that when you link a local table with a remote table (ex. ODBC) it’s incredibly slow. Often my MS Access will freeze up, making me think the application will crash.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I’ve been using MS Access for years, I’ve only noticed this as an issue “recently” — I’m currently using Microsoft 365 Apps for enterprise.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Avoid Local Tables in MS Access
&lt;/h2&gt;

&lt;p&gt;The obvious way is to put your data into another remote (SQL Server) table.&lt;/p&gt;

&lt;p&gt;My suggested approach is a little faster: rather than creating (or modifying) a new table every time, add WHERE criteria.&lt;/p&gt;

&lt;p&gt;As a web developer, I use an IDE (specifically Sublime Text, but this also works with VS Code). You can &lt;strong&gt;select multiple lines by clicking the mouse wheel&lt;/strong&gt;, and then move the cursor over (via “Home” and “End” keys) to surround the text in a single quote and append the word “or”:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rh2FVoSL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6cnvmdotaxsl7lro5mvm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rh2FVoSL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6cnvmdotaxsl7lro5mvm.png" alt="Use the mouse wheel to select multiple rows" width="560" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You could also do this with an Excel formula:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jfBPpuYy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lbvw102vfjh123ekdqaj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jfBPpuYy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lbvw102vfjh123ekdqaj.png" alt="Use an Excel formula to specify criteria" width="355" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then query the (one) SQL server table and specify additional criteria:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JWKG8mFU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3w8hcrhhbyb2hq319cur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JWKG8mFU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3w8hcrhhbyb2hq319cur.png" alt="New query in MS Access" width="399" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This approach may not be reasonable for “a lot” of data, but if you’re querying for a handful of items it may be a viable alternative.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This technique greatly speeds up the time it takes me to query a SQL Server table via MS Access when performing data analysis.&lt;/p&gt;

</description>
      <category>data</category>
      <category>msaccess</category>
      <category>dataanalystics</category>
      <category>sql</category>
    </item>
    <item>
      <title>Two Ways To Create Totals In SQL</title>
      <dc:creator>Steve Sohcot</dc:creator>
      <pubDate>Mon, 20 Jun 2022 00:25:16 +0000</pubDate>
      <link>https://forem.com/stevesohcot/two-ways-to-create-totals-in-sql-21bl</link>
      <guid>https://forem.com/stevesohcot/two-ways-to-create-totals-in-sql-21bl</guid>
      <description>&lt;p&gt;When presenting tabular data (i.e. data in a table), you may want to have a “total” row at the bottom.&lt;/p&gt;

&lt;p&gt;I remember (~25!) years ago I took the approach of creating a multi-dimensional array to sum a value, row-by-row, and column-by-column. Both server-side and in JavaScript.&lt;/p&gt;

&lt;p&gt;It’s more efficient to create a “total” row in SQL (server side). It’ll also make it easier for the front-end developer.&lt;/p&gt;

&lt;p&gt;To start with, let’s assume we have a sample query like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5JpNLXUR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dte8ul260xejqc9i0lgw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5JpNLXUR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dte8ul260xejqc9i0lgw.png" alt="Original Query" width="248" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Method 1: Creating a SQL Total with UNION ALL
&lt;/h2&gt;

&lt;p&gt;The first approach I’ll mention is to basically create a copy of your dataset:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the copy, exclude the first column that displays the different values&lt;/li&gt;
&lt;li&gt;Hard-code the word “Total” to ensure that the same number of columns appear in each dataset&lt;/li&gt;
&lt;li&gt;Join the two datasets together via &lt;em&gt;UNION ALL&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Wrap both together in a surrounding &lt;em&gt;SELECT&lt;/em&gt; statement&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Remember to remove the &lt;em&gt;ORDER BY&lt;/em&gt; within the sub-queries.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We now have a “Total” row, but it doesn’t appear at the bottom of the dataset:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O4cqNdlF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b7yjtnnz0o8cp5s7tveu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O4cqNdlF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b7yjtnnz0o8cp5s7tveu.png" alt="“Total” isn’t the last one there" width="250" height="140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can fix this by updating our &lt;em&gt;ORDER BY&lt;/em&gt; clause to include a &lt;em&gt;CASE&lt;/em&gt; statement:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Explanation: Where ever the column says “Total” give it a value of 1, and all other entries are 0. Therefore, Total will always be at the end. As a secondary sort, use the other field (here, “agent”).&lt;/p&gt;

&lt;p&gt;Now we have the Total at the end:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uHVvA1CH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2djy2mn00wukrkbqmu9r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uHVvA1CH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2djy2mn00wukrkbqmu9r.png" alt="“Total” is correctly the last one" width="250" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Method 2: Creating a SQL total with ROLLUP
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;This may be specific to the version of SQL you’re using. I know it works with MS SQL Server&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can simply add the function &lt;em&gt;ROLLUP&lt;/em&gt; immediately after the &lt;em&gt;GROUP BY&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Be sure to include the parenthesis&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This works, but you’ll see that it shows a value of &lt;em&gt;NULL&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---mrW3fQ---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhipexvss5j82gapni99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---mrW3fQ---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhipexvss5j82gapni99.png" alt="Total appears as NULL" width="258" height="142"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, to make it easier for the front-end developer, we can resolve this by replacing &lt;em&gt;NULL&lt;/em&gt; with “Total”.&lt;/p&gt;

&lt;p&gt;Just doing that won’t be enough, you’ll need to use the same ‘sorting’ trick previously mentioned:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Note that I’m replacing &lt;em&gt;NULL&lt;/em&gt; with “Total” in multiple instances&lt;/p&gt;

&lt;h2&gt;
  
  
  One last trick for SQL Subtotals
&lt;/h2&gt;

&lt;p&gt;I often want to have my “Total” be the last row. Sometimes I’ll have a value of “Other” that I want to be second-to-last (rather than display alphabetically). Using the &lt;em&gt;CASE&lt;/em&gt; statement in the &lt;em&gt;ORDER BY&lt;/em&gt; clause again, we can achieve this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://stevesohcot.medium.com/two-ways-to-create-totals-in-sql-1f77f24067c5"&gt;Originally posted on Medium&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>analytics</category>
      <category>sql</category>
      <category>database</category>
    </item>
    <item>
      <title>What's The Ideal Pagination From A UI/UX Perspective?</title>
      <dc:creator>Steve Sohcot</dc:creator>
      <pubDate>Sat, 30 Apr 2022 03:04:59 +0000</pubDate>
      <link>https://forem.com/stevesohcot/whats-the-ideal-pagination-from-a-uiux-perspective-20l3</link>
      <guid>https://forem.com/stevesohcot/whats-the-ideal-pagination-from-a-uiux-perspective-20l3</guid>
      <description>&lt;p&gt;When you Google something, there are probably millions of results. But they don't display all of them at once.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pagination is the term web developers use to show only some of the results within a dataset&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You're showing only some results, then there will be an option for "go to the next page," or some equivalent.&lt;/p&gt;

&lt;p&gt;There are several variations of pagination. I recently sought out to answer, &lt;strong&gt;from a UI/UX view, what is the ideal pagination format?&lt;/strong&gt; What's the most practical (dare I say, "best")?&lt;/p&gt;

&lt;h2&gt;
  
  
  Pagination Benefits
&lt;/h2&gt;

&lt;p&gt;Why use pagination? Two major benefits come to mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's easier for users to digest small chunks of information&lt;/li&gt;
&lt;li&gt;It helps with the page load. Loading 10 results is much faster than 1,000 results (think seconds it takes a website to display)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pagination Examples
&lt;/h2&gt;

&lt;p&gt;This is so common amongst web developers that UI web libraries have pre-built design templates. For example, here's the &lt;a href="https://getbootstrap.com/docs/5.1/components/pagination/"&gt;default Bootstrap design&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L3WR-orS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xcqgq7da0exvzversdtl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L3WR-orS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xcqgq7da0exvzversdtl.png" alt="Pagination for Bootstrap v5.1" width="276" height="75"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google has a unique one:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6PDEaUPv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2iirfrz28t1h805fsbcx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6PDEaUPv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2iirfrz28t1h805fsbcx.png" alt="This solution may not work for you" width="351" height="91"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I remember &lt;em&gt;several&lt;/em&gt; years ago, I did something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dXYBTPpE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/klib9bvqna000wgnnk0k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dXYBTPpE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/klib9bvqna000wgnnk0k.png" alt="Recreation of my first attempt at pagination, circa 2001" width="283" height="111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Prior to going on this quest, this was my previous standard:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9cWwYhvb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0rniekvunleb5zn81h12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9cWwYhvb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0rniekvunleb5zn81h12.png" alt="Pagination Example" width="221" height="32"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see it has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First/Last icons&lt;/li&gt;
&lt;li&gt;Previous/Next icons&lt;/li&gt;
&lt;li&gt;Page you’re on&lt;/li&gt;
&lt;li&gt;Total number of pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That was pretty simple (and simple is good!) but of course I thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Was there a better way?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Assumption: Search vs Browse
&lt;/h2&gt;

&lt;p&gt;You're not remaking Google. You won't have a million results.&lt;/p&gt;

&lt;p&gt;Your app should have a "search" capability that will allow a user to narrow down the results. Maybe it’ll be 100 or even 1,000 results. After a search, the user may sort the results. Overall it’ll be a rather small dataset.&lt;/p&gt;

&lt;p&gt;If the user isn’t sure what they're looking for, then they are browsing the entire dataset.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For my use case, I'm using pagination for when a user is browsing an entire dataset.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Initial logic in designing the ideal pagination
&lt;/h2&gt;

&lt;p&gt;Using Google as an inspiration and a lot of thought, this was my first pass:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3L7hP0PE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h787amo1rkxlznk9b5m5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3L7hP0PE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h787amo1rkxlznk9b5m5.png" alt="Initial pagination; using MDBootstrap" width="260" height="416"&gt;&lt;/a&gt;&lt;br&gt;
Considerations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First/Last buttons (if applicable)&lt;/li&gt;
&lt;li&gt;Previous/Next buttons (if applicable)&lt;/li&gt;
&lt;li&gt;Numeric indicators&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  No Need For First/Last Buttons
&lt;/h2&gt;

&lt;p&gt;When you perform a search, you expect to see the most relevant results first. If the results aren't on the page, you'll go to the next page. And maybe even the one after that.&lt;/p&gt;

&lt;p&gt;Once you're in the "middle" of the search results, you most likely won't have a desire to go back to the first page. Similarly, you probably won't have a need to skip to the last page; if you were that interested, you’d sort the results descending. &lt;strong&gt;As such, no need to show "First/Last" options.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Previous/Next
&lt;/h2&gt;

&lt;p&gt;Assuming the results aren't on the first page, and you're actually utilizing pagination, you'll need Previous/Next buttons.&lt;/p&gt;

&lt;p&gt;Only show if applicable. For example, when viewing the first page of results, don’t show a "Previous" button. Or at minimum, have it displayed but disabled (unclickable).&lt;/p&gt;

&lt;p&gt;Two comments of interest when I was talking to &lt;a href="https://www.york-myers.com/"&gt;York Myers&lt;/a&gt;, a friend who's a UI/UX expert:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consider using the term "Back" instead of "Previous". Fewer letters will be more consistent with the term "Next".&lt;/li&gt;
&lt;li&gt;Use icons (ex. arrow) if possible. Be mindful of your users though: depending on the demographic, it may be more clear to explicitly spell-out "Next" rather than have an arrow.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Page Numbers
&lt;/h2&gt;

&lt;p&gt;A couple of obvious things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Show the current ("active") page that the user is on&lt;/li&gt;
&lt;li&gt;In addition to Previous (Back) / Next buttons, have a clickable button that has the page number on it. If you’re on Page 1, then have a button for "Page 2" and a button for "Next".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not as obvious:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many numeric buttons do you need? After some thought and discussion, I think it should be no more than two numbers, before and/or after the current page the user is on. This is demonstrated in the image above.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  (2) Final Recommendations
&lt;/h2&gt;

&lt;p&gt;I think the logic in the preceding recommendation is ideal, however there was another suggestion offered. Take a look at the component below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5tEkbBxU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oawmocr6j5cbxuqbb6kh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5tEkbBxU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oawmocr6j5cbxuqbb6kh.png" alt="Material Design for Bootstrap: Data tables component" width="412" height="62"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Option to select rows per page (here, a dropdown with 10 pre-selected)&lt;/li&gt;
&lt;li&gt;Displaying the current set of results (here, 1 to 10)&lt;/li&gt;
&lt;li&gt;Total number of results (here, 14)&lt;/li&gt;
&lt;li&gt;Previous / Next &lt;em&gt;as icons&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That simplifies things, but personally I don't want to give the user an option to select the number of results to show.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Showing less options &amp;gt;&amp;gt; User has to think less&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I realized that this is what GMail does. Another ideal pagination design pattern then becomes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vfcD3AY0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/06a23bxl54gb90m2d5mh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vfcD3AY0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/06a23bxl54gb90m2d5mh.png" alt="Gmail example" width="191" height="37"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;I'm a web developer with 20+ years experience. While I’m not a UI/UX expert, I’ve picked up a thing or two over the years and I did consult one for this article. Your comments/opinions are welcome!&lt;/p&gt;




&lt;p&gt;This article was originally &lt;a href="https://stevesohcot.medium.com/whats-the-ideal-pagination-from-a-ui-ux-perspective-d2d954a8126"&gt;posted on Medium&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ux</category>
      <category>uiweekly</category>
      <category>html</category>
    </item>
  </channel>
</rss>
