---
title: "ClickHouse® tips #10: Null behavior with LowCardinality columns"
excerpt: "Does it work? What's actually inserted? Part 10."
authors: "Alejandro del Amo"
categories: "The Data Base"
createdOn: "2023-09-25 00:00:00"
publishedOn: "2021-07-21 00:00:00"
updatedOn: "2022-09-08 00:00:00"
status: "published"
---

<p>If you have LowCardinality(String) column with clickhouse lowcardinality optimization, inserting a NULL value will work fine. It will just treat it like you just have inserted an empty string (''). Let's see an example with clickhouse nullable columns.</p><figure class="kg-card kg-embed-card"><iframe loading="lazy" width="100%" src="https://snippets.tinybird.co/endpoint?code=DESKTOP-TNFN1JU.localdomain%20%3A%29%20CREATE%20TABLE%20checking%28test%20LowCardinality%28String%29%29%20ENGINE%20MergeTree%28%29%20ORDER%20BY%20tuple%28%29%0A%0ACREATE%20TABLE%20checking%0A%28%0A%20%20%20%20%60test%60%20LowCardinality%28String%29%0A%29%0AENGINE%20%3D%20MergeTree%0AORDER%20BY%20tuple%28%29%0A%0AQuery%20id%3A%2058bcefee-9021-44de-a38d-b460bfef44d8%0A%0AOk.%0A%0A0%20rows%20in%20set.%20Elapsed%3A%200.026%20sec.%0A&amp;language=shell&amp;title=Creating%20a%20table%20with%20a%20LowCardinality%28String%29%20column&amp;run=&amp;token="></iframe></figure><p>Let’s insert some values now.</p><figure class="kg-card kg-embed-card"><iframe loading="lazy" width="100%" src="https://snippets.tinybird.co/endpoint?code=DESKTOP-TNFN1JU.localdomain%20%3A%29%20INSERT%20INTO%20checking%20VALUES%20%28NULL%29%0A%0AINSERT%20INTO%20checking%20VALUES%0A%0AQuery%20id%3A%20b91ac9ce-efa9-49dd-915e-cc56413894dd%0A%0AOk.%0A%0A1%20rows%20in%20set.%20Elapsed%3A%200.019%20sec.%0A&amp;language=shell&amp;title=Inserting%20a%20null%20value%20into%20the%20table&amp;run=&amp;token="></iframe></figure><p>And now let’s see what has been inserted. As you can see, even though we inserted a NULL value, internally it’s saved as an empty string.</p><figure class="kg-card kg-embed-card"><iframe loading="lazy" width="100%" src="https://snippets.tinybird.co/endpoint?code=DESKTOP-TNFN1JU.localdomain%20%3A%29%20SELECT%20%2A%20FROM%20checking%0A%0ASELECT%20%2A%0AFROM%20checking%0A%0AQuery%20id%3A%2008f204fa-82f8-41e1-9ff0-278503dabec4%0A%0A%E2%94%8C%E2%94%80test%E2%94%80%E2%94%90%0A%E2%94%82%20%20%20%20%20%20%E2%94%82%0A%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%0A1%20rows%20in%20set.%20Elapsed%3A%200.004%20sec.%0A%0ADESKTOP-TNFN1JU.localdomain%20%3A%29%20SELECT%20%2A%20FROM%20checking%20WHERE%20test%20IS%20NULL%0A%0ASELECT%20%2A%0AFROM%20checking%0AWHERE%20isNull%28test%29%0A%0AQuery%20id%3A%207f3390c5-7a5a-473c-8bae-1548ba801c34%0A%0AOk.%0A%0A0%20rows%20in%20set.%20Elapsed%3A%200.004%20sec.%0A%0ADESKTOP-TNFN1JU.localdomain%20%3A%29%20SELECT%20%2A%20FROM%20checking%20WHERE%20test%20%3D%20%27%27%0A%0ASELECT%20%2A%0AFROM%20checking%0AWHERE%20test%20%3D%20%27%27%0A%0AQuery%20id%3A%20af19f3e2-a53d-4933-9aa6-d8381b4ef431%0A%0A%E2%94%8C%E2%94%80test%E2%94%80%E2%94%90%0A%E2%94%82%20%20%20%20%20%20%E2%94%82%0A%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%0A1%20rows%20in%20set.%20Elapsed%3A%200.004%20sec.%0A%0A&amp;language=shell&amp;title=snippet_title&amp;run=&amp;token="></iframe></figure><h2 id="bonus-can-you-create-lowcardinalitynullablestring-columns">Bonus: can you create clickhouse nullable column types with LowCardinality(Nullable(String))?</h2><p>Yes, you can.</p><p>Using <code>LowCardinality(Nullable(String))</code> instead of <code>Nullable(String)</code>, apart of the benefits that it can bring <code>LowCardinality</code> if the conditions are right, also allows you to order by that column. See an example here:</p><figure class="kg-card kg-embed-card"><iframe loading="lazy" width="100%" src="https://snippets.tinybird.co/endpoint?code=DESKTOP-TNFN1JU.localdomain%20%3A%29%20CREATE%20TABLE%20test2%20%28a%20Nullable%28String%29%29%20ENGINE%3DMergeTree%28%29%20ORDER%20BY%20a%3B%0A%0ACREATE%20TABLE%20test2%0A%28%0A%20%20%20%20%60a%60%20Nullable%28String%29%0A%29%0AENGINE%20%3D%20MergeTree%28%29%0AORDER%20BY%20a%0A%0A%0AReceived%20exception%20from%20server%20%28version%2020.7.2%29%3A%0ACode%3A%2044.%20DB%3A%3AException%3A%20Received%20from%20localhost%3A9000.%20DB%3A%3AException%3A%20Sorting%20key%20cannot%20contain%20nullable%20columns.%0A%0A0%20rows%20in%20set.%20Elapsed%3A%200.508%20sec.%0A%0ADESKTOP-TNFN1JU.localdomain%20%3A%29%20CREATE%20TABLE%20test2%20%28a%20LowCardinality%28Nullable%28String%29%29%29%20ENGINE%3DMergeTree%28%29%20ORDER%20BY%20a%3B%0A%0ACREATE%20TABLE%20test2%0A%28%0A%20%20%20%20%60a%60%20LowCardinality%28Nullable%28String%29%29%0A%29%0AENGINE%20%3D%20MergeTree%28%29%0AORDER%20BY%20a%0A%0AOk.%0A%0A0%20rows%20in%20set.%20Elapsed%3A%200.011%20sec.%0A%0ADESKTOP-TNFN1JU.localdomain%20%3A%29%20INSERT%20INTO%20test2%20VALUES%20%28NULL%29%0A%0AINSERT%20INTO%20test2%20VALUES%0A%0AOk.%0A%0A1%20rows%20in%20set.%20Elapsed%3A%200.021%20sec.%0A%0ADESKTOP-TNFN1JU.localdomain%20%3A%29%20SELECT%20%2A%20FROM%20test2%0A%0ASELECT%20%2A%0AFROM%20test2%0A%0A%E2%94%8C%E2%94%80a%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%E2%94%82%20%E1%B4%BA%E1%B5%81%E1%B4%B8%E1%B4%B8%20%E2%94%82%0A%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%0A1%20rows%20in%20set.%20Elapsed%3A%200.025%20sec.%0A%0ADESKTOP-TNFN1JU.localdomain%20%3A%29%20%20SELECT%20%2A%20FROM%20test2%20WHERE%20a%20IS%20NULL%3B%0A%0ASELECT%20%2A%0AFROM%20test2%0AWHERE%20isNull%28a%29%0A%0A%E2%94%8C%E2%94%80a%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%E2%94%82%20%E1%B4%BA%E1%B5%81%E1%B4%B8%E1%B4%B8%20%E2%94%82%0A%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%0A1%20rows%20in%20set.%20Elapsed%3A%200.011%20sec.%0A%0ADESKTOP-TNFN1JU.localdomain%20%3A%29%20%20SELECT%20%2A%20FROM%20test2%20WHERE%20a%20%3D%20%27%27%3B%0A%0ASELECT%20%2A%0AFROM%20test2%0AWHERE%20a%20%3D%20%27%27%0A%0AOk.%0A%0A0%20rows%20in%20set.%20Elapsed%3A%200.012%20sec.%0A&amp;language=shell&amp;title=Using%20LowCardinality%28Nullable%28String%29%29%20columns&amp;run=&amp;token="></iframe></figure>
