[{"data":1,"prerenderedAt":226},["ShallowReactive",2],{"page:\u002Fen\u002Fguides\u002Funknown-is-not-zero":3},{"id":4,"title":5,"body":6,"description":218,"extension":219,"meta":220,"navigation":221,"path":222,"seo":223,"stem":224,"__hash__":225},"pages\u002Fen\u002Fguides\u002Funknown-is-not-zero.md","Storing unknown: why null is not 0",{"type":7,"value":8,"toc":209},"minimark",[9,25],[10,11,13,20],"page-head",{"updated":12},"22 October 2026",[14,15,17],"template",{"v-slot:title":16},"",[18,19,5],"p",{},[14,21,22],{"v-slot:lead":16},[18,23,24],{},"Yes, no and we don't know are three answers. Store them as three too.",[26,27,28,33,41,44,99,103,109,118,122,135,141,150,154,167,175,179,182,186],"article-body",{},[29,30,32],"h2",{"id":31},"three-answers","Three answers",[18,34,35,36,40],{},"Does a company have a webshop? The answer is yes, no or we don't know. A field with two states can only hold two. If you pick ",[37,38,39],"code",{},"false"," as the default, we don't know quietly becomes no.",[18,42,43],{},"The same goes for numbers and lists. Zero open vacancies is not the same as a number you don't know, and an empty list is not the same as a list you don't know.",[45,46,47,60],"table",{},[48,49,50],"thead",{},[51,52,53,57],"tr",{},[54,55,56],"th",{},"Meaning",[54,58,59],{},"Value",[61,62,63,72,89],"tbody",{},[51,64,65,69],{},[66,67,68],"td",{},"Known",[66,70,71],{},"the value",[51,73,74,77],{},[66,75,76],{},"No, zero or none",[66,78,79,81,82,85,86],{},[37,80,39],{},", ",[37,83,84],{},"0"," or ",[37,87,88],{},"[]",[51,90,91,94],{},[66,92,93],{},"Unknown",[66,95,96],{},[37,97,98],{},"null",[29,100,102],{"id":101},"in-your-database","In your database",[18,104,105,106,108],{},"Let the column allow ",[37,107,98],{},", and give it no default value:",[110,111,116],"pre",{"className":112,"code":114,"language":115,"meta":16},[113],"language-sql","create table companies (\n  kvk_number     char(8) primary key,\n  webshop        boolean,  -- null: unknown\n  open_vacancies integer,  -- null: unknown\n  known_count    integer not null\n);\n","sql",[37,117,114],{"__ignoreMap":16},[29,119,121],{"id":120},"counting-with-unknown","Counting with unknown",[18,123,124,127,128,131,132,134],{},[37,125,126],{},"avg"," and ",[37,129,130],{},"count(column)"," skip ",[37,133,98],{},". That is what you want: the average covers the companies you know it for.",[110,136,139],{"className":137,"code":138,"language":115,"meta":16},[113],"-- the average of the companies we know it for\nselect avg(open_vacancies) from companies;\n\n-- wrong: unknown now counts as zero\nselect avg(coalesce(open_vacancies, 0)) from companies;\n",[37,140,138],{"__ignoreMap":16},[18,142,143,146,147,149],{},[37,144,145],{},"count(*)"," counts the rows, including those with ",[37,148,98],{},". Put the two side by side and you see how much you know.",[29,151,153],{"id":152},"in-your-code","In your code",[18,155,156,157,160,161,163,164,166],{},"A check like ",[37,158,159],{},"if (!company.webshop)"," treats ",[37,162,98],{}," as ",[37,165,39],{},". So compare exactly:",[110,168,173],{"className":169,"code":171,"language":172,"meta":16},[170],"language-js","if (company.webshop === null) show('unknown')\nelse if (company.webshop) show('webshop')\nelse show('no webshop')\n","js",[37,174,171],{"__ignoreMap":16},[29,176,178],{"id":177},"on-screen","On screen",[18,180,181],{},"Show unknown as the word unknown. A dash or a blank cell looks like no, or like an error.",[29,183,185],{"id":184},"at-achtcijfers","At Achtcijfers",[18,187,188,189,191,192,195,196,81,198,85,200,202,203,208],{},"A field we don't know is ",[37,190,98],{}," in the API. The ",[37,193,194],{},"known"," object counts the fields we do know, as a number: so you can sort and filter, for example on companies where you know at least five fields. A ",[37,197,39],{},[37,199,84],{},[37,201,88],{}," counts as known. More on ",[204,205,207],"a",{"href":206},"\u002Fen\u002Fapi","API",".",{"title":16,"searchDepth":210,"depth":210,"links":211},2,[212,213,214,215,216,217],{"id":31,"depth":210,"text":32},{"id":101,"depth":210,"text":102},{"id":120,"depth":210,"text":121},{"id":152,"depth":210,"text":153},{"id":177,"depth":210,"text":178},{"id":184,"depth":210,"text":185},"Yes, no and we don't know are three answers. How to store them in your database and your code, so unknown does not quietly turn into no.","md",{},true,"\u002Fen\u002Fguides\u002Funknown-is-not-zero",{"title":5,"description":218},"en\u002Fguides\u002Funknown-is-not-zero","CVkxqiXNO7wp3muM4vgyMLj_PWpljaHOOvkD51iXDlY",1793465541382]