Using MySQL Magic Numbers with If and Case

Updated on February 20, 2021
Using MySQL Magic Numbers with If and Case header image

Introduction

When designing applications in MySQL, you'll encounter scenarios that require heavy use of magic numbers. These are constant values that won't immediately make sense to anyone with little knowledge of how your database works. For instance, assume you're creating a microfinance bank database. If you've got a table named charges that can either have penalties or fees, you might use the characters P and F to denote the information in a column named charge_type.

For this information to be useful, you must spell out the magic numbers when presenting the information to the frontend desktop or mobile applications. This is where the MySQL IF and CASE statements come into play. In this guide, you will use the MySQL IF and CASE statements to run logical tests against different table values to spell out magic numbers in a human-readable format in a hypothetical microfinance bank database running on Ubuntu 20.04.

Prerequisites

Before you proceed, you'll require the following:

Create a Test microfinance Database

SSH to your server and run the command below to log in to the MySQL server as root.

$ sudo mysql -u root -p

Enter the root password of your MySQL server and press Enter to continue. Once you get the mysql> prompt, run the command below to create a microfinance database.

mysql> CREATE DATABASE microfinance;

Switch to the microfinance database.

mysql> USE microfinance;

Next, create a charges table. You'll define some columns using the MySQL CHAR() data type in this table. This column will hold some magic numbers.

mysql> CREATE TABLE charges
       (
           charge_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
           applies_to CHAR(1),
           charge_type CHAR(1),
           charge_name VARCHAR(50),
           frequency  CHAR(1),
           amount DECIMAL(17,2)
       ) ENGINE = InnoDB;

Insert some records to the charges table so that you can begin exploring how the MySQL IF and CASE functions work. For the basis of this tutorial, you'll use the following magic numbers when populating the charges table.

The applies_to column:

  • C - CLIENTS ACCOUNTS
  • S - SAVINGS ACCOUNTS
  • I - INVESMENT/SHARES ACCOUNTS
  • L - LOAN ACCOUNTS

The charge_type column:

  • F - FEE
  • P - PENALTY

The frequency column:

  • O - ONE TIME
  • R - RECURRING

Begin by entering a one-time registration fee for the CLIENTS accounts.

mysql> INSERT INTO charges(applies_to, charge_type, charge_name, frequency, amount) VALUES ('C', 'F', 'REGISTRATION FEE', 'O', '500');

Next, add a one-time SAVINGS ACCOUNTS withdrawal fee, a recurring monthly ledger fee, and a one-time lateness penalty.

mysql> INSERT INTO charges(applies_to, charge_type, charge_name, frequency, amount) VALUES ('S', 'F', 'WITHDRAWAL FEE', 'O', '10');
mysql> INSERT INTO charges(applies_to, charge_type, charge_name, frequency, amount) VALUES ('S', 'F', 'MONTHLY LEDGER FEE', 'R', '50');
mysql> INSERT INTO charges(applies_to, charge_type, charge_name, frequency, amount) VALUES ('S', 'P', 'LATENESS PENALTY', 'O', '5');

Then, enter a one-time redemption fee and purchase fee for the SHARES/INVESTMENTS ACCOUNTS.

mysql> INSERT INTO charges(applies_to, charge_type, charge_name, frequency, amount) VALUES ('I', 'F', 'REDEMTION FEE', 'O', '10');
mysql> INSERT INTO charges(applies_to, charge_type, charge_name, frequency, amount) VALUES ('I', 'F', 'PURCHASE FEEE', 'O', '50');

Finally, insert a one-time application fee and a recurring lateness penalty for the LOANS ACCOUNTS.

mysql> INSERT INTO charges(applies_to, charge_type, charge_name, frequency, amount) VALUES ('L', 'F', 'APPLICATION FEE', 'O', '10');
mysql> INSERT INTO charges(applies_to, charge_type, charge_name, frequency, amount) VALUES ('L', 'P', 'LATENESS PENALTY','R', '50');

After running each INSERT command above, ensure you get the output below.

...

Query OK, 1 row affected (0.04 sec)

Query the charges table to make sure the data is in place.

mysql> SELECT
       charge_id,
       applies_to,
       charge_type,
       charge_name,
       frequency,
       amount
       FROM charges;

As you can see from the output below, the raw data might not make sense to someone who is not familiar with the meaning of your magic numbers. This design pattern is great when it comes to saving disk space, optimizing and speeding up queries in your database.

+-----------+------------+-------------+--------------------+-----------+--------+
| charge_id | applies_to | charge_type | charge_name        | frequency | amount |
+-----------+------------+-------------+--------------------+-----------+--------+
|         1 | C          | F           | REGISTRATION FEE   | O         | 500.00 |
|         2 | S          | F           | WITHDRAWAL FEE     | O         |  10.00 |
|         3 | S          | F           | MONTHLY LEDGER FEE | R         |  50.00 |
|         4 | S          | P           | LATENESS PENALTY   | O         |   5.00 |
|         5 | I          | F           | REDEMTION FEE      | O         |  10.00 |
|         6 | I          | F           | PURCHASE FEEE      | O         |  50.00 |
|         7 | L          | F           | APPLICATION FEE    | O         |  10.00 |
|         8 | L          | P           | LATENESS PENALTY   | R         |  50.00 |
+-----------+------------+-------------+--------------------+-----------+--------+
8 rows in set (0.00 sec)

In the next step, you'll use the MySQL IF and CASE statements to spell out those magic numbers for reporting purposes.

Spell Out the Magic Numbers

In MySQL, you can use the IF statement to evaluate a value stored in a column and return different results depending on whether the evaluation results to true or false. Use the general syntax below when using an IF statement in MySQL.

mysql> IF ([EVALUATION], [VALUE IF TRUE], [VALUE IF FALSE];

To put this in a better perspective, run the command below to spell out the full string values(That is, either FEE or PENALTY) for the charge_type column in your charges table.

mysql> SELECT
       charge_id,
       applies_to,
       IF (charge_type = 'F', 'FEE', 'PENALTY') AS charge_type,
       charge_name,
       frequency,
       amount
       FROM charges;

As you might have noted from the output below, the information displayed in the charge_type column is now human-readable and is no longer ambiguous.

+-----------+------------+-------------+--------------------+-----------+--------+
| charge_id | applies_to | charge_type | charge_name        | frequency | amount |
+-----------+------------+-------------+--------------------+-----------+--------+
|         1 | C          | FEE         | REGISTRATION FEE   | O         | 500.00 |
|         2 | S          | FEE         | WITHDRAWAL FEE     | O         |  10.00 |
|         3 | S          | FEE         | MONTHLY LEDGER FEE | R         |  50.00 |
|         4 | S          | PENALTY     | LATENESS PENALTY   | O         |   5.00 |
|         5 | I          | FEE         | REDEMTION FEE      | O         |  10.00 |
|         6 | I          | FEE         | PURCHASE FEEE      | O         |  50.00 |
|         7 | L          | FEE         | APPLICATION FEE    | O         |  10.00 |
|         8 | L          | PENALTY     | LATENESS PENALTY   | R         |  50.00 |
+-----------+------------+-------------+--------------------+-----------+--------+
8 rows in set (0.00 sec)

Apply the same syntax to the frequency column and spell out the full string values for the columns (either ONE TIME or RECURRING).

mysql> SELECT
       charge_id,
       applies_to,
       IF (charge_type = 'F', 'FEE', 'PENALTY') AS charge_type,
       charge_name,
       IF (frequency = 'O', 'ONE TIME', 'RECURRING') AS frequency,
       amount
       FROM charges;

The frequency column is now spelled out, as shown below.

+-----------+------------+-------------+--------------------+-----------+--------+
| charge_id | applies_to | charge_type | charge_name        | frequency | amount |
+-----------+------------+-------------+--------------------+-----------+--------+
|         1 | C          | FEE         | REGISTRATION FEE   | ONE TIME  | 500.00 |
|         2 | S          | FEE         | WITHDRAWAL FEE     | ONE TIME  |  10.00 |
|         3 | S          | FEE         | MONTHLY LEDGER FEE | RECURRING |  50.00 |
|         4 | S          | PENALTY     | LATENESS PENALTY   | ONE TIME  |   5.00 |
|         5 | I          | FEE         | REDEMTION FEE      | ONE TIME  |  10.00 |
|         6 | I          | FEE         | PURCHASE FEEE      | ONE TIME  |  50.00 |
|         7 | L          | FEE         | APPLICATION FEE    | ONE TIME  |  10.00 |
|         8 | L          | PENALTY     | LATENESS PENALTY   | RECURRING |  50.00 |
+-----------+------------+-------------+--------------------+-----------+--------+
8 rows in set (0.00 sec)

The IF function is mostly suitable for column names that contain utmost two different values unless you opt to use nested statements. If you're evaluating more than two values, the MySQL CASE statement is suitable for that purpose. The following is a basic syntax of the MySQL CASE statement.

mysql> CASE
       WHEN [EVALUATION  ONE] THEN [VALUE IF EVALUATION ONE IS TRUE]
       WHEN [EVALUATION  TWO] THEN [VALUE IF EVALUATION TWO IS TRUE]
       WHEN [EVALUATION    N] THEN [VALUE IF EVALUATION N   IS TRUE]
       ELSE [VALUE FOR ANY OTHER CONDITION NOT LISTED ABOVE]
       END AS [NEW COLUMN VALUE]

For instance, to spell out the full string values for the applies_to column in the charges table, use the command below.

mysql> SELECT
       charge_id,
       CASE
           WHEN applies_to = 'C' THEN 'CLIENTS ACCOUNTS'
           WHEN applies_to = 'S' THEN 'SAVINGS ACCOUNTS'
           WHEN applies_to = 'I' THEN 'SHARES/INVESMENTS ACCOUNTS'
           ELSE 'LOANS ACCOUNTS'
       END AS applies_to,
       IF (charge_type = 'F', 'FEE', 'PENALTY') AS charge_type,
       charge_name,
       IF (frequency = 'O', 'ONE TIME', 'RECURRING') AS frequency,
       amount
       FROM charges;

The MySQL CASE statement should work as expected as you can confirm from the following output.

+-----------+----------------------------+-------------+--------------------+-----------+--------+
| charge_id | applies_to                 | charge_type | charge_name        | frequency | amount |
+-----------+----------------------------+-------------+--------------------+-----------+--------+
|         1 | CLIENTS ACCOUNTS           | FEE         | REGISTRATION FEE   | ONE TIME  | 500.00 |
|         2 | SAVINGS ACCOUNTS           | FEE         | WITHDRAWAL FEE     | ONE TIME  |  10.00 |
|         3 | SAVINGS ACCOUNTS           | FEE         | MONTHLY LEDGER FEE | RECURRING |  50.00 |
|         4 | SAVINGS ACCOUNTS           | PENALTY     | LATENESS PENALTY   | ONE TIME  |   5.00 |
|         5 | SHARES/INVESMENTS ACCOUNTS | FEE         | REDEMTION FEE      | ONE TIME  |  10.00 |
|         6 | SHARES/INVESMENTS ACCOUNTS | FEE         | PURCHASE FEEE      | ONE TIME  |  50.00 |
|         7 | LOANS ACCOUNTS             | FEE         | APPLICATION FEE    | ONE TIME  |  10.00 |
|         8 | LOANS ACCOUNTS             | PENALTY     | LATENESS PENALTY   | RECURRING |  50.00 |
+-----------+----------------------------+-------------+--------------------+-----------+--------+
8 rows in set (0.00 sec)

As you might have noted from the outputs of all the SELECT commands that you've run, the IF and CASE statements are great for spelling out the magic numbers when it comes to displaying actual string names for abbreviated column values.

Conclusion

In this guide, you've used the MySQL IF and CASE statements to spell out magic numbers in a hypothetical microfinance database. Adopt the code in this guide when creating your next MySQL project.