{"id":196495,"date":"2025-07-07T09:10:26","date_gmt":"2025-07-07T08:10:26","guid":{"rendered":"https:\/\/liora.io\/en\/?p=196495"},"modified":"2026-08-09T19:53:24","modified_gmt":"2026-08-09T18:53:24","slug":"handling-missing-values-in-sql","status":"publish","type":"post","link":"https:\/\/liora.io\/en\/handling-missing-values-in-sql","title":{"rendered":"Handling Missing Values in SQL: A Practical Guide"},"content":{"rendered":"\n<p><strong>Missing values are one of the most common data quality issues. If not handled properly, they can bias your reports, skew insights, or hurt forecasting accuracy. In SQL, there are several ways to detect, interpret, and manage missing values depending on the context.<\/strong><\/p>\n\n\n<h2 class=\"wp-block-heading\" id=\"step-1-identify-missing-values\">? Step 1: Identify Missing Values<\/h2>\n\n\n<p>Before you handle missing values, you must first understand how they are represented in your dataset. \u201cMissing\u201d does not always mean NULL ,  it can take many forms.<\/p>\n\n\n<p>Here are the most common types and how to detect them:<\/p>\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table>\n<colgroup>\n<col\/>\n<col\/>\n<col\/>\n<\/colgroup>\n<thead>\n<tr>\n<th>Type<\/th>\n<th>Meaning<\/th>\n<th>Detection in SQL<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>NULL<\/td>\n<td>Official SQL representation of a missing value<\/td>\n<td>WHERE column IS NULL<\/td>\n<\/tr>\n<tr>\n<td>Empty String<\/td>\n<td>Value is an empty pair of quotes (&#8221;)<\/td>\n<td>WHERE column = &#8221;<\/td>\n<\/tr>\n<tr>\n<td>Blank Space<\/td>\n<td>User input contains only spaces<\/td>\n<td>WHERE TRIM(column) = &#8221;<\/td>\n<\/tr>\n<tr>\n<td>Zero (0)<\/td>\n<td>May represent missing in some numeric fields<\/td>\n<td>WHERE column = 0<\/td>\n<\/tr>\n<tr>\n<td>Textual \u201cmissing\u201d<\/td>\n<td>Non-standard representations like &#8216;N\/A&#8217;, &#8216;unknown&#8217;, etc.<\/td>\n<td>WHERE LOWER(column) IN (&#8216;n\/a&#8217;, &#8216;unknown&#8217;, &#8216;missing&#8217;, &#8216;null&#8217;, &#8216;-&#8216;)<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n<p>? <em>Tip: Standardize the representations when possible, especially before ingestion if you control upstream data.<\/em><\/p>\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex is-content-justification-center wp-container-core-buttons-is-layout-5ee10de4\" style=\"margin-top:32px;margin-bottom:32px\"><div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"\/en\/courses\/data-ai\/data-analyst\">Learn SQL for Data Science<\/a><\/div><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"step-2-manage-missing-values\">? Step 2: Manage Missing Values<\/h2>\n\n\n<p>Imagine you are working with a customer table like this:<\/p>\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table>\n<colgroup>\n<col\/>\n<col\/>\n<col\/>\n<col\/>\n<col\/>\n<col\/>\n<\/colgroup>\n<thead>\n<tr>\n<th>customer_id<\/th>\n<th>first_name<\/th>\n<th>last_name<\/th>\n<th>email<\/th>\n<th>email_verified<\/th>\n<th>phone_number<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>101<\/td>\n<td>John<\/td>\n<td>Doe<\/td>\n<td>john@email.com<\/td>\n<td>Y<\/td>\n<td>0912&#8230;<\/td>\n<\/tr>\n<tr>\n<td>102<\/td>\n<td>Jane<\/td>\n<td>Smith<\/td>\n<td>NULL<\/td>\n<td>NULL<\/td>\n<td>0933&#8230;<\/td>\n<\/tr>\n<tr>\n<td>103<\/td>\n<td>Mike<\/td>\n<td>Lee<\/td>\n<td>&#8221;<\/td>\n<td>N<\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n<p>You are planning an email campaign where each email costs money, so you want to avoid sending to people with unverified or missing email addresses.<\/p>\n\n\n<h3 class=\"wp-block-heading\" id=\"option-1-exclude-missing-or-unverified-emails\">\u2705 Option 1: Exclude Missing or Unverified Emails<\/h3>\n\n\n<p>If you only want to send to users with a verified email (Y), you can write:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>SELECT *\n\nFROM customers\n\nWHERE LOWER(email_verified) = 'y'\n\n\u00a0\u00a0AND email IS NOT NULL\n\n\u00a0\u00a0AND TRIM(email) &lt;&gt; '';<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"option-2-use-coalesce-to-substitute-missing-info\">? Option 2: Use COALESCE to Substitute Missing Info<\/h3>\n\n\n<p>Normally, you would only trust customers with email_verified = &#8216;Y&#8217;. But based on internal logic, you decide to treat email addresses as valid if the customer has a phone number, even if the email_verified column is missing or marked as &#8216;N&#8217;.<\/p>\n\n\n<p>You can implement this logic using a combination of CASE WHEN and COALESCE:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>SELECT customer_id, email\n\nFROM (\n\n\u00a0\u00a0SELECT customer_id,\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0email,\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CASE\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0WHEN LOWER(email_verified) = 'y' THEN 'Y'\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0WHEN COALESCE(TRIM(phone_number), '') &lt;&gt; '' THEN 'Y'\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ELSE 'N'\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0END AS email_verified_updated\n\n\u00a0\u00a0FROM customers\n\n) AS t\n\nWHERE email_verified_updated = 'Y'\n\n\u00a0\u00a0AND COALESCE(TRIM(email), '') &lt;&gt; '';<\/code><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id=\"important-considerations\">\u26a0\ufe0f Important Considerations<\/h2>\n\n\n<ol class=\"wp-block-list\">\n<li aria-level=\"1\">Know your data: Missing values can appear in different formats. Explore your data before applying filters or replacements.<\/li>\n<li aria-level=\"1\">Do not blindly drop rows: Excluding missing data without evaluating its impact can lead to biased results or missed opportunities (e.g., important customers).<\/li>\n<li aria-level=\"1\">Communicate with stakeholders: Align on what counts as \u201cmissing\u201d and push for upstream data validation to avoid recurring issues.<\/li>\n<li aria-level=\"1\">Document your rules: Your logic for handling missing values should be transparent and reproducible.<\/li>\n<\/ol>\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">\u2705 Conclusion<\/h2>\n\n\n<p>Handling missing values in <a href=\"https:\/\/liora.io\/en\/sql-tutorial-top-5-most-useful-methods\">SQL<\/a> is not just about cleaning data ,  it is about making smart, context-aware decisions that <strong>preserve insight quality<\/strong> and business impact. Whether you are identifying true NULLs, interpreting unconventional missing markers, or applying business logic to fill gaps, the key is to approach the task intentionally.<\/p>\n\n\n<p>Remember:<\/p>\n\n\n<ul class=\"wp-block-list\">\n<li aria-level=\"1\"><strong>Explore first<\/strong> ,  understand how missing values are represented in your dataset.<\/li>\n<li aria-level=\"1\"><strong>Act selectively<\/strong> ,  not all missing values should be removed; some may be handled through logic.<\/li>\n<li><strong>Think practically<\/strong> ,  missing values often reflect real-world constraints, so align with stakeholders on how to interpret and treat them.<\/li>\n<\/ul>\n\n\n<p>By thoughtfully identifying and managing missing values, you will build analyses that are not only cleaner, but also more trustworthy and actionable.<\/p>\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex is-content-justification-center wp-container-core-buttons-is-layout-5ee10de4\" style=\"margin-top:32px;margin-bottom:32px\"><div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"\/en\/courses\/data-ai\/data-analyst\">\nLearn to handle missing values in SQL\n<\/a><\/div><\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>Missing values are one of the most common data quality issues. If not handled properly, they can bias your reports, skew insights, or hurt forecasting accuracy. In SQL, there are several ways to detect, interpret, and manage missing values depending on the context. ? Step 1: Identify Missing Values Before you handle missing values, you [&hellip;]<\/p>\n","protected":false},"author":99,"featured_media":196496,"comment_status":"open","ping_status":"open","sticky":false,"template":"elementor_theme","format":"standard","meta":{"_acf_changed":false,"editor_notices":[],"footnotes":""},"categories":[2433],"class_list":["post-196495","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-data-ai"],"acf":[],"_links":{"self":[{"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/posts\/196495","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/users\/99"}],"replies":[{"embeddable":true,"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/comments?post=196495"}],"version-history":[{"count":5,"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/posts\/196495\/revisions"}],"predecessor-version":[{"id":211193,"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/posts\/196495\/revisions\/211193"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/media\/196496"}],"wp:attachment":[{"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/media?parent=196495"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/categories?post=196495"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}