➤ Check for NULL:
SELECT * FROM Students WHERE Email IS NULL;➤ Replace NULL values (useful for display):
SELECT COALESCE(Age, 'Not Provided') FROM Students;<div class="infographic-null-handling">
<style>
.infographic-null-handling {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--mono-font: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
background: var(--paper);
color: var(--ink);
padding: 2rem 1.5rem 2.5rem;
max-width: 720px;
margin: 0 auto;
box-sizing: border-box;
}
.infographic-null-handling[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
}
.infographic-null-handling *, .infographic-null-handling *::before, .infographic-null-handling *::after {
box-sizing: border-box;
}
.infographic-null-handling h2 {
font-size: 1.4rem;
margin: 0 0 0.25rem;
letter-spacing: -0.01em;
}
.infographic-null-handling .subtitle {
color: var(--ink-soft);
font-size: 0.92rem;
margin: 0 0 1.5rem;
max-width: 54ch;
}
.infographic-null-handling .tabs {
display: inline-flex;
background: var(--paper-alt);
border-radius: 999px;
padding: 4px;
margin-bottom: 1.1rem;
gap: 4px;
}
.infographic-null-handling .tab {
font: inherit;
font-size: 0.82rem;
font-weight: 700;
padding: 0.5rem 1rem;
border-radius: 999px;
border: none;
background: transparent;
color: var(--ink-soft);
cursor: pointer;
transition: background 0.2s ease, color 0.2s ease;
white-space: nowrap;
}
.infographic-null-handling .tab.is-active {
background: var(--accent);
color: #fff;
}
.infographic-null-handling .query-box {
background: #1e1e26;
border-radius: 10px;
padding: 0.85rem 1rem;
margin-bottom: 0.9rem;
overflow-x: auto;
}
.infographic-null-handling .query-box pre {
margin: 0;
font-family: var(--mono-font);
font-size: 0.82rem;
color: #d9d6ce;
white-space: pre;
}
.infographic-null-handling .query-box .kw { color: #7aa2ff; font-weight: 600; }
.infographic-null-handling .query-box .fn { color: #f2c94c; }
.infographic-null-handling .query-box .str { color: #6fcf97; }
.infographic-null-handling .controls {
display: flex;
align-items: center;
gap: 0.6rem;
margin-bottom: 1rem;
flex-wrap: wrap;
}
.infographic-null-handling .btn {
font: inherit;
font-size: 0.82rem;
font-weight: 700;
padding: 0.5rem 1rem;
border-radius: 999px;
border: 1px solid var(--accent);
background: var(--accent);
color: #fff;
cursor: pointer;
transition: opacity 0.15s ease;
}
.infographic-null-handling .btn:hover { opacity: 0.9; }
.infographic-null-handling .btn.ghost {
background: transparent;
color: var(--ink-soft);
border-color: var(--line);
}
.infographic-null-handling .btn.ghost:hover {
border-color: var(--accent);
color: var(--accent);
opacity: 1;
}
.infographic-null-handling .run-caption {
font-size: 0.8rem;
color: var(--ink-soft);
}
.infographic-null-handling .run-caption strong { color: var(--accent); }
.infographic-null-handling table {
width: 100%;
border-collapse: collapse;
font-size: 0.85rem;
background: var(--paper-alt);
border-radius: 12px;
overflow: hidden;
}
.infographic-null-handling thead th {
text-align: left;
font-size: 0.68rem;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--ink-soft);
padding: 0.55rem 0.75rem;
background: var(--paper-alt);
font-family: var(--mono-font);
border-bottom: 1px solid var(--line);
}
.infographic-null-handling tbody tr {
background: var(--paper);
transition: opacity 0.3s ease, background 0.3s ease;
}
.infographic-null-handling tbody td {
padding: 0.55rem 0.75rem;
border-top: 1px solid var(--line);
}
.infographic-null-handling tbody tr.is-match {
background: var(--accent-soft);
}
.infographic-null-handling tbody tr.is-match td:first-child {
box-shadow: inset 3px 0 0 var(--accent);
}
.infographic-null-handling tbody tr.is-dim {
opacity: 0.4;
}
.infographic-null-handling .null-tag {
font-family: var(--mono-font);
font-size: 0.74rem;
font-style: italic;
color: var(--ink-soft);
background: var(--paper-alt);
padding: 0.1rem 0.4rem;
border-radius: 5px;
}
.infographic-null-handling .replaced-tag {
font-family: var(--mono-font);
font-size: 0.76rem;
font-weight: 700;
color: var(--accent);
opacity: 0;
transform: translateY(-2px);
animation: null-fade-in 0.35s ease forwards;
}
@keyframes null-fade-in {
to { opacity: 1; transform: translateY(0); }
}
.infographic-null-handling .takeaway {
margin-top: 1.5rem;
font-size: 0.88rem;
color: var(--ink-soft);
border-left: 3px solid var(--accent);
padding: 0.5rem 0 0.5rem 0.9rem;
}
.infographic-null-handling .takeaway strong { color: var(--ink); }
@media (max-width: 520px) {
.infographic-null-handling table { font-size: 0.76rem; }
.infographic-null-handling thead th,
.infographic-null-handling tbody td { padding: 0.45rem 0.5rem; }
}
@media (prefers-reduced-motion: reduce) {
.infographic-null-handling *, .infographic-null-handling *::before, .infographic-null-handling *::after {
animation-duration: 0.001ms !important;
transition-duration: 0.001ms !important;
}
}
</style>
<h2>Handling NULL in SQL</h2>
<p class="subtitle">Two things you'll do with NULL constantly: find it, or hide it from the people reading your results. Run both against the same table.</p>
<div class="tabs" role="tablist">
<button class="tab is-active" type="button" data-key="check">🔍 Check for NULL</button>
<button class="tab" type="button" data-key="coalesce">🔄 Replace NULL</button>
</div>
<div class="query-box">
<pre id="sql-text"><span class="kw">SELECT</span> * <span class="kw">FROM</span> Students <span class="kw">WHERE</span> Email <span class="kw">IS NULL</span>;</pre>
</div>
<div class="controls">
<button class="btn" id="btn-run" type="button">▶ Run query</button>
<button class="btn ghost" id="btn-reset" type="button">↺ Reset</button>
<span class="run-caption" id="run-caption">Click run to see which rows match.</span>
</div>
<table>
<thead>
<tr><th>ID</th><th>Name</th><th>Email</th><th>Age</th></tr>
</thead>
<tbody id="students-body">
<tr data-email="set" data-age="set">
<td>101</td><td>Aisha</td><td>aisha@mail.com</td><td>20</td>
</tr>
<tr data-email="null" data-age="set">
<td>102</td><td>Rahul</td><td><span class="null-tag">NULL</span></td><td>22</td>
</tr>
<tr data-email="set" data-age="null">
<td>103</td><td>Meera</td><td>meera@mail.com</td><td><span class="null-tag">NULL</span></td>
</tr>
<tr data-email="null" data-age="set">
<td>104</td><td>Karan</td><td><span class="null-tag">NULL</span></td><td>19</td>
</tr>
<tr data-email="set" data-age="null">
<td>105</td><td>Priya</td><td>priya@mail.com</td><td><span class="null-tag">NULL</span></td>
</tr>
</tbody>
</table>
<p class="takeaway"><strong>COALESCE only changes what you see.</strong> The stored Age is still NULL — the query just substitutes a display value for that one result set.</p>
<script>
(function () {
var wrapper = document.currentScript.closest('.infographic-null-handling')
|| document.querySelector('.infographic-null-handling');
var bodyAttr = document.body.getAttribute('data-darkmode');
var dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
var match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
var CONFIG = {
check: {
sql: '<span class="kw">SELECT</span> * <span class="kw">FROM</span> Students <span class="kw">WHERE</span> Email <span class="kw">IS NULL</span>;',
prompt: 'Click run to filter down to only the matching rows.',
result: '<strong>2 rows</strong> remain — every row where Email isn\'t NULL was filtered out.'
},
coalesce: {
sql: '<span class="kw">SELECT</span> <span class="fn">COALESCE</span>(Age, <span class="str">\'Not Provided\'</span>) <span class="kw">FROM</span> Students;',
prompt: 'Click run to replace missing Age values for display.',
result: 'Every NULL Age now displays as <strong>"Not Provided"</strong> — Email is untouched since the query only wraps Age.'
}
};
var tabs = wrapper.querySelectorAll('.tab');
var sqlText = wrapper.querySelector('#sql-text');
var runCaption = wrapper.querySelector('#run-caption');
var btnRun = wrapper.querySelector('#btn-run');
var btnReset = wrapper.querySelector('#btn-reset');
var rows = wrapper.querySelectorAll('#students-body tr');
var currentKey = 'check';
function resetTable() {
rows.forEach(function (row) {
row.classList.remove('is-match', 'is-dim');
row.style.display = '';
var ageCell = row.children[3];
if (row.getAttribute('data-age') === 'null' && ageCell.querySelector('.replaced-tag')) {
ageCell.innerHTML = '<span class="null-tag">NULL</span>';
}
});
}
function runCheck() {
rows.forEach(function (row) {
var isMatch = row.getAttribute('data-email') === 'null';
row.classList.toggle('is-match', isMatch);
row.style.display = isMatch ? '' : 'none';
});
}
function runCoalesce() {
rows.forEach(function (row) {
var ageCell = row.children[3];
if (row.getAttribute('data-age') === 'null') {
ageCell.innerHTML = '<span class="replaced-tag">Not Provided</span>';
}
});
}
function loadTab(key) {
currentKey = key;
var cfg = CONFIG[key];
sqlText.innerHTML = cfg.sql;
runCaption.innerHTML = cfg.prompt;
resetTable();
}
btnRun.addEventListener('click', function () {
if (currentKey === 'check') {
runCheck();
} else {
runCoalesce();
}
runCaption.innerHTML = CONFIG[currentKey].result;
});
btnReset.addEventListener('click', function () {
resetTable();
runCaption.innerHTML = CONFIG[currentKey].prompt;
});
tabs.forEach(function (tab) {
tab.addEventListener('click', function () {
tabs.forEach(function (t) { t.classList.remove('is-active'); });
tab.classList.add('is-active');
loadTab(tab.getAttribute('data-key'));
});
});
loadTab('check');
})();
</script>
</div>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});