<?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>DEV Community: Dechive</title>
    <description>The latest articles on DEV Community by Dechive (@dechive).</description>
    <link>https://dev.to/dechive</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%2F3897598%2F705e6c9c-58dd-4046-85df-b3804702d917.png</url>
      <title>DEV Community: Dechive</title>
      <link>https://dev.to/dechive</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dechive"/>
    <language>en</language>
    <item>
      <title>Why WHERE phone = NULL Returns Nothing in SQL</title>
      <dc:creator>Dechive</dc:creator>
      <pubDate>Sun, 10 May 2026 15:33:56 +0000</pubDate>
      <link>https://dev.to/dechive/why-where-phone-null-returns-nothing-in-sql-m1j</link>
      <guid>https://dev.to/dechive/why-where-phone-null-returns-nothing-in-sql-m1j</guid>
      <description>&lt;p&gt;If you are new to SQL, this query can look perfectly reasonable at first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have a &lt;code&gt;users&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;Some users did not enter their phone number.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;phone&lt;/code&gt; column looks empty.&lt;/p&gt;

&lt;p&gt;So you try to find those rows with &lt;code&gt;phone = NULL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But the result comes back empty.&lt;/p&gt;

&lt;p&gt;The table is not necessarily wrong.&lt;br&gt;
The column name may be correct.&lt;br&gt;
The query may even look logical.&lt;/p&gt;

&lt;p&gt;The problem is that &lt;code&gt;NULL&lt;/code&gt; is not a normal value.&lt;/p&gt;

&lt;p&gt;To understand why this query returns nothing, we need to understand what &lt;code&gt;NULL&lt;/code&gt; really means.&lt;/p&gt;
&lt;h2&gt;
  
  
  NULL is not an empty value
&lt;/h2&gt;

&lt;p&gt;At first, &lt;code&gt;NULL&lt;/code&gt; looks like an empty cell.&lt;/p&gt;

&lt;p&gt;It feels similar to &lt;code&gt;0&lt;/code&gt; or an empty string.&lt;/p&gt;

&lt;p&gt;But in SQL, these are different things:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0      -&amp;gt; a number
''     -&amp;gt; an empty string
NULL   -&amp;gt; an unknown or unrecorded state
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;0&lt;/code&gt; is a value.&lt;/p&gt;

&lt;p&gt;It means the number zero.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;''&lt;/code&gt; is also a value.&lt;/p&gt;

&lt;p&gt;It means a string with no characters.&lt;/p&gt;

&lt;p&gt;But &lt;code&gt;NULL&lt;/code&gt; is different.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NULL&lt;/code&gt; does not mean “empty” in the same way.&lt;br&gt;
It means the value is unknown, missing, or not recorded.&lt;/p&gt;

&lt;p&gt;That difference looks small, but it affects comparisons, calculations, and aggregate functions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why &lt;code&gt;= NULL&lt;/code&gt; does not work
&lt;/h2&gt;

&lt;p&gt;Look again at the original query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This condition asks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is phone equal to NULL?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But &lt;code&gt;NULL&lt;/code&gt; means unknown.&lt;/p&gt;

&lt;p&gt;SQL cannot say that one unknown value is equal to another unknown value.&lt;/p&gt;

&lt;p&gt;Even this expression is not true:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is not &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is unknown.&lt;/p&gt;

&lt;p&gt;And &lt;code&gt;WHERE&lt;/code&gt; only keeps rows where the condition is true.&lt;/p&gt;

&lt;p&gt;So when you write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SQL does not find the rows where &lt;code&gt;phone&lt;/code&gt; is &lt;code&gt;NULL&lt;/code&gt;.&lt;br&gt;
The comparison itself does not become true.&lt;/p&gt;

&lt;p&gt;That is why the correct query is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if you want rows where &lt;code&gt;phone&lt;/code&gt; has a value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;IS NULL&lt;/code&gt; is not just another style of writing &lt;code&gt;= NULL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It asks a different question:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is this value in an unknown or unrecorded state?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  NULL spreads through calculations
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;NULL&lt;/code&gt; also affects calculations.&lt;/p&gt;

&lt;p&gt;If an unknown value is part of a calculation, the result is usually unknown too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;-- NULL&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;-- NULL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes sense if you think about what &lt;code&gt;NULL&lt;/code&gt; means.&lt;/p&gt;

&lt;p&gt;If you do not know one part of the calculation, you cannot know the final result.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;item_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Imagine this table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;item_id&lt;/th&gt;
&lt;th&gt;price&lt;/th&gt;
&lt;th&gt;quantity&lt;/th&gt;
&lt;th&gt;total&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If &lt;code&gt;price&lt;/code&gt; is unknown, the total is unknown.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;quantity&lt;/code&gt; is unknown, the total is also unknown.&lt;/p&gt;

&lt;p&gt;The calculation is not broken.&lt;br&gt;
SQL is preserving the fact that something is unknown.&lt;/p&gt;

&lt;p&gt;Sometimes you may want to replace &lt;code&gt;NULL&lt;/code&gt; with another value.&lt;/p&gt;

&lt;p&gt;For that, SQL provides &lt;code&gt;COALESCE&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;item_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;COALESCE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;COALESCE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;COALESCE(price, 0)&lt;/code&gt; means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use price if it is not NULL.
If price is NULL, use 0 instead.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this should be done carefully.&lt;/p&gt;

&lt;p&gt;Replacing &lt;code&gt;NULL&lt;/code&gt; with &lt;code&gt;0&lt;/code&gt; is not just a technical fix.&lt;br&gt;
It changes the meaning of the data.&lt;/p&gt;

&lt;p&gt;There is a difference between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The value is zero.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;We do not know the value.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SQL keeps that difference visible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aggregate functions treat NULL differently
&lt;/h2&gt;

&lt;p&gt;There is another place where &lt;code&gt;NULL&lt;/code&gt; often surprises beginners.&lt;/p&gt;

&lt;p&gt;Aggregate functions usually skip &lt;code&gt;NULL&lt;/code&gt; values.&lt;/p&gt;

&lt;p&gt;For example, imagine a &lt;code&gt;score&lt;/code&gt; column with these values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;80, NULL, 90, NULL, 70
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now look at this query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
       &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
       &lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
       &lt;span class="k"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;SUM(score)&lt;/code&gt; returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;240
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It does not treat &lt;code&gt;NULL&lt;/code&gt; as &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It skips the unknown values.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AVG(score)&lt;/code&gt; returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because it calculates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(80 + 90 + 70) / 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It does not divide by all five rows.&lt;/p&gt;

&lt;p&gt;That is important.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NULL&lt;/code&gt; is not zero.&lt;br&gt;
It is ignored by many aggregate functions.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;code&gt;COUNT(*)&lt;/code&gt; and &lt;code&gt;COUNT(column)&lt;/code&gt; are different
&lt;/h2&gt;

&lt;p&gt;The most common mistake is with &lt;code&gt;COUNT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Look at this query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
       &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These two expressions do not ask the same question.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;COUNT(*)&lt;/code&gt; asks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How many rows are there?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;COUNT(score)&lt;/code&gt; asks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How many rows have a known value in the score column?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if the table has five rows, but only three rows have a score:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COUNT(*)     -&amp;gt; 5
COUNT(score) -&amp;gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both answers are correct.&lt;/p&gt;

&lt;p&gt;They are just answering different questions.&lt;/p&gt;

&lt;p&gt;This matters in real data.&lt;/p&gt;

&lt;p&gt;The number of users is not always the same as the number of users with phone numbers.&lt;/p&gt;

&lt;p&gt;The number of orders is not always the same as the number of orders with payment dates.&lt;/p&gt;

&lt;p&gt;The number of rows is not always the number of known values.&lt;/p&gt;

&lt;h2&gt;
  
  
  NULL is a record of uncertainty
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;NULL&lt;/code&gt; is not just an empty space.&lt;/p&gt;

&lt;p&gt;It is a mark left by uncertainty.&lt;/p&gt;

&lt;p&gt;A user did not enter a phone number.&lt;br&gt;
A measurement was not recorded.&lt;br&gt;
A delivery address was not decided yet.&lt;br&gt;
A value was not known when the row was stored.&lt;/p&gt;

&lt;p&gt;That is why this does not work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is why this becomes &lt;code&gt;NULL&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is why these two counts are different:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;column&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They all come from the same idea:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Unknown values remain unknown until we decide how to handle them.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sometimes we replace them.&lt;/p&gt;

&lt;p&gt;Sometimes we exclude them.&lt;/p&gt;

&lt;p&gt;Sometimes we leave them as they are.&lt;/p&gt;

&lt;p&gt;The database is honest about what it does not know.&lt;/p&gt;

&lt;p&gt;How we read that uncertainty is up to us.&lt;/p&gt;




&lt;p&gt;Originally published at Dechive:&lt;br&gt;
&lt;a href="https://dechive.dev/en/archive/what-null-leaves-behind" rel="noopener noreferrer"&gt;https://dechive.dev/en/archive/what-null-leaves-behind&lt;/a&gt;&lt;/p&gt;




</description>
      <category>beginners</category>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>We Do Not Teach Thinking to AI</title>
      <dc:creator>Dechive</dc:creator>
      <pubDate>Sat, 09 May 2026 21:39:00 +0000</pubDate>
      <link>https://dev.to/dechive/we-do-not-teach-thinking-to-ai-5d06</link>
      <guid>https://dev.to/dechive/we-do-not-teach-thinking-to-ai-5d06</guid>
      <description>&lt;p&gt;Most of us learned to prompt AI by &lt;em&gt;guiding&lt;/em&gt; its thinking.&lt;/p&gt;

&lt;p&gt;"Think step by step."&lt;br&gt;&lt;br&gt;
"Here's an example of how to solve this."&lt;br&gt;&lt;br&gt;
"First check A, then compare B, finally conclude with C."&lt;/p&gt;

&lt;p&gt;These techniques made sense — because we were working with models that needed a path. Without structure, they'd rush to a conclusion.&lt;/p&gt;

&lt;p&gt;But reasoning models shift this premise.&lt;/p&gt;




&lt;h2&gt;
  
  
  Thinking Comes Before the Answer
&lt;/h2&gt;

&lt;p&gt;General conversational models excel at producing natural answers quickly. For tasks where the direction is clear — brief summaries, simple explanations — this is sufficient.&lt;/p&gt;

&lt;p&gt;Reasoning models work differently. Rather than pushing problems straight toward conclusions, they're designed to &lt;strong&gt;compare conditions, trace possible paths, and hold problems longer&lt;/strong&gt; before forming answers.&lt;/p&gt;

&lt;p&gt;Models like Claude's extended thinking or OpenAI's o-series represent this direction — built to spend more computation on internal reasoning.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A reasoning model isn't one that writes longer answers. It's one built to grapple with harder problems for longer.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  When Your Old Methods Get in the Way
&lt;/h2&gt;

&lt;p&gt;With general models, "think step by step" can be helpful. It forces intermediate steps rather than jumping to conclusions.&lt;/p&gt;

&lt;p&gt;But with reasoning models, the same approach doesn't always work.&lt;/p&gt;

&lt;p&gt;When you strongly specify an arbitrary sequence of thinking to a model &lt;strong&gt;already designed to break problems down&lt;/strong&gt;, you narrow the space for it to find a better path.&lt;/p&gt;

&lt;p&gt;The same goes for examples. Good examples show the standard for an answer. But overly detailed examples can lock the model into a specific solution method — even when a superior approach exists.&lt;/p&gt;

&lt;p&gt;This isn't about Chain of Thought being wrong. It's about using the same habits when your tool has fundamentally changed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Specify the Goal, Then Step Back
&lt;/h2&gt;

&lt;p&gt;With reasoning models, sometimes saying &lt;em&gt;less&lt;/em&gt; is better.&lt;/p&gt;

&lt;p&gt;Rather than mapping out the process in detail, give:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A clear &lt;strong&gt;goal&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;criteria&lt;/strong&gt; for a good answer
&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;output format&lt;/strong&gt; you need&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then leave the middle steps to the model.&lt;/p&gt;

&lt;p&gt;The model doesn't need you to design its thinking process. It needs to know what counts as a good answer.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is an excerpt. The full piece — including a side-by-side prompt comparison and when reasoning models are the wrong tool entirely — is at &lt;a href="https://dechive.dev/en/archive/prompt-reasoning-model" rel="noopener noreferrer"&gt;Dechive&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dechive is a quiet library for the AI age — a place to read slowly, think deeply, and ask why.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>discuss</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Why Artificial Intelligence Tells Lies</title>
      <dc:creator>Dechive</dc:creator>
      <pubDate>Mon, 13 Apr 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/dechive/why-artificial-intelligence-tells-lies-1dp5</link>
      <guid>https://dev.to/dechive/why-artificial-intelligence-tells-lies-1dp5</guid>
      <description>&lt;p&gt;Before a Professional Industrial Hygiene Exam, I asked an AI to solve some past questions. It got the answers wrong. That part was fine. The problem was how perfectly it explained its wrong answers. It cited relevant laws, analyzed each option one by one, and laid out the logic of why its answer was correct. Confidently. Flawlessly.&lt;/p&gt;

&lt;p&gt;Suspicious, I told it the correct answer directly. The AI didn't back down. It insisted its choice was right and that the answer I'd given was actually wrong. At the end, I uploaded both the test sheet and answer key as files. Still wrong.&lt;/p&gt;

&lt;p&gt;This wasn't a bug.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not a Lie, But Certainty
&lt;/h3&gt;

&lt;p&gt;It's acceptable that AI produces wrong answers. Every system gets things wrong sometimes.&lt;/p&gt;

&lt;p&gt;What's hard to accept is something else: the AI doesn't know it was wrong.&lt;/p&gt;

&lt;p&gt;A lie means knowing the truth and hiding it. Hallucination is different. A model may not generate enough signals to itself that the answer is incorrect. It lacks any sense of being wrong. Because of this, wrong information doesn't look wrong. There's logic to it, evidence behind it, a stable tone.&lt;/p&gt;

&lt;p&gt;This is what sets hallucination apart from other kinds of errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Does It Speak Without Knowing?
&lt;/h3&gt;

&lt;p&gt;An LLM doesn't work the way humans understand text. It's closer to a machine that predicts the most plausible token coming next in a given context. The measure of "plausibility" isn't factual accuracy—it's what followed similar patterns in the training data.&lt;/p&gt;

&lt;p&gt;When asked "What is the workers' compensation standard for noise-induced hearing loss?", the model generates the most natural text that would follow such a question. If older standards appear more frequently in the training data, it confidently outputs the outdated standard instead of the current one. There's no way for it to know it's wrong.&lt;/p&gt;

&lt;p&gt;Even when you provide the correct answer, its stubbornness stems from the same source. The model holds two kinds of knowledge: the billions of parameters inscribed during training, and the information the user provides in this conversation. When these collide, context doesn't always win. Information the model learned strongly tends to override what the user says in the moment.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;How can we reduce these hallucinations? And what are the limits that prompts simply cannot overcome?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://dechive.dev/en/archive/prompt-hallucination" rel="noopener noreferrer"&gt;Continue reading the full article at Dechive →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dechive is a bilingual digital library for deep thinking about AI, prompt engineering, and technology.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>beginners</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
