postgresql處理空值NULL與替換的問(wèn)題解決辦法
開(kāi)頭還是介紹一下群,如果感興趣polardb ,mongodb ,mysql ,postgresql ,redis 等有問(wèn)題,有需求都可以加群群內(nèi)有各大數(shù)據(jù)庫(kù)行業(yè)大咖,CTO,可以解決你的問(wèn)題。加群請(qǐng)加微信liuaustin3 ,(共1140人左右 1 + 2 + 3)新人會(huì)進(jìn)入3群
最近一直在研究關(guān)于POSTGRESQL 開(kāi)發(fā)方面的一些技巧和問(wèn)題,本期是關(guān)于在開(kāi)發(fā)中的一些關(guān)于NULL 值處理的問(wèn)題。在業(yè)務(wù)開(kāi)發(fā)中,經(jīng)常會(huì)遇到輸入的值為NULL 但是實(shí)際上我們需要代入默認(rèn)值的問(wèn)題,而通常的處理方法是,在字段加入默認(rèn)值設(shè)置,讓不輸入的情況下,替換NULL值,同時(shí)還具備另一個(gè)字段類(lèi)型轉(zhuǎn)換的功能。
1 默認(rèn)值取代NULL
2 處理程序可選字段的值為空的情況
3 數(shù)據(jù)轉(zhuǎn)換和類(lèi)型的轉(zhuǎn)換
下面我們看看如何進(jìn)行實(shí)際中的相關(guān)事例
事例1 程序中在需要兩個(gè)字段進(jìn)行計(jì)算后,得出結(jié)果進(jìn)行展示,比如買(mǎi)一送一,或買(mǎi)一送二 等,我們先創(chuàng)建一個(gè)表
CREATE TABLE IF NOT EXISTS public.disaccount ( id serial NOT NULL, store_id smallint NOT NULL, first_name character varying(45) COLLATE pg_catalog."default" NOT NULL, last_name character varying(45) COLLATE pg_catalog."default" NOT NULL, sell_number smallint NOT NULL, sell_discount float, sell_update timestamp without time zone DEFAULT now(), CONSTRAINT pkey_id PRIMARY KEY (id)) TABLESPACE pg_default;
在上圖中,我們可以看到由于打折的數(shù)字是沒(méi)有的,而在查詢(xún)中導(dǎo)致由于部分商品在購(gòu)買(mǎi)中沒(méi)有打折,而導(dǎo)致最后付款的實(shí)際錢(qián)數(shù)為0。在這樣的情況下,那么在這樣的情況下,我們可以使用POSTGRESQL 提供的函數(shù)來(lái)解決這個(gè)問(wèn)題。
這里采用了coalesce 函數(shù),在 sell_discount 為NULL的情況下,則我們用1來(lái)替代這個(gè)值,保證最終計(jì)算的邏輯結(jié)果是正確的。
實(shí)際上,如果在設(shè)計(jì)表的時(shí)候,給這個(gè)字段的默認(rèn)值為1 ,也可以解決這個(gè)問(wèn)題,但是如果早期未做處理,上線(xiàn)后數(shù)據(jù)量較大,也可以用coalesce 來(lái)解決這個(gè)問(wèn)題,并且使用這個(gè)函數(shù)是靈活的,后面NULL 可以替代的值也是你可以隨意指定的。
問(wèn)題2 在一個(gè)程序邏輯中,有三個(gè)字段,但是其中只能有一個(gè)字段可以被展示,其他的字段的值為NULL,比如一個(gè)猜盒子里面有什么的程序,盒子里面有什么是一個(gè)已經(jīng)預(yù)定好的情況,并且在開(kāi)獎(jiǎng)的時(shí)候,需要給出到底那個(gè)盒子里面有獎(jiǎng)品。
我們?cè)诮⑦@樣一個(gè)表
drop table guess_what; create table guess_what (id serial primary key, first_name varchar(20), last_name varchar(20), box1 varchar(10), box2 varchar(10), box3 varchar(10), date_time timestamp without time zone DEFAULT now()); insert into guess_what (first_name,last_name,box2) values ('Simon','Almbo','box2'); insert into guess_what (first_name,last_name,box3) values ('Lisa','Slmeb','box3');
select first_name || '.' || last_name, coalesce(box1,box2,box3) as guess_what,date_time from guess_what;a
那么這樣的情況下,如果不使用coalesce 函數(shù)有什么辦法來(lái)進(jìn)行操作嗎?
我們?cè)賮?lái)看
select first_name || '.' || last_name, case when box1 is not null then box1 when box2 is not null then box2 when box3 is not null then box3 end as guess_what, date_time from guess_what;
a
那么除了上面的兩種使用的情況,COALESCE 還可以針對(duì)某些字段的類(lèi)型進(jìn)行轉(zhuǎn)換,如日期類(lèi)型轉(zhuǎn)換為文字的需求。
如我們?cè)谌掌诶锩媸荖ULL 的情況下,我們不想展示為NULL,而是展示的
時(shí)候,為我們想用其他的文字來(lái)代替它。
select id, COALESCE(CAST(date_time AS TEXT), 'date_time') AS date_time from guess_what;
a
上面的例子就是我們?cè)卺槍?duì)date_time 字段時(shí)間類(lèi)型的數(shù)據(jù)在他是NULL的情況下,展示出來(lái)我們指定的其他類(lèi)型的文字,相關(guān)的寫(xiě)法如上。COALESCE可以與其他條件邏輯(如CASE)結(jié)合使用,這基于特定條件或標(biāo)準(zhǔn)對(duì)NULL值進(jìn)行更復(fù)雜的處理。通過(guò)利用COALESCE的靈活性并將其與條件邏輯相結(jié)合,您可以實(shí)現(xiàn)更復(fù)雜的數(shù)據(jù)轉(zhuǎn)換和替換。
附:PG的空值相加如何實(shí)現(xiàn)
PostgreSQL數(shù)據(jù)庫(kù)中,對(duì)于NULL值相加的處理:任何數(shù)值和NULL相加都得NULL。
postgres=# create table t3(id1 int,id2 int); CREATE TABLE postgres=# insert into t3 select 1,2; INSERT 0 1 postgres=# insert into t3 select 1,NULL; INSERT 0 1 postgres=# insert into t3 select NULL,NULL; INSERT 0 1 postgres=# insert into t3 select NULL,3; INSERT 0 1 postgres=# select *from t3; id1 | id2 -----+----- 1 | 2 1 | | | 3 (4 行記錄)
看下加的結(jié)果:
postgres=# select id1+id2 from t3;
?column?
----------
3
(4 行記錄)
可以看到只要有一個(gè)參數(shù)是NULL,那么加的結(jié)果就是NULL。那么這個(gè)計(jì)算是如何實(shí)現(xiàn)的呢?
從前文可以了解到操作符“+”的實(shí)現(xiàn)機(jī)制,真正執(zhí)行是在ExecInterpExpr函數(shù)中:
ExecInterpExpr EEO_CASE(EEOP_FUNCEXPR_STRICT)//操作符函數(shù)的執(zhí)行 { FunctionCallInfo fcinfo = op->d.func.fcinfo_data; NullableDatum *args = fcinfo->args; int argno; Datum d; /* strict function, so check for NULL args */ for (argno = 0; argno < op->d.func.nargs; argno++) { if (args[argno].isnull) { *op->resnull = true;//只要有一個(gè)參數(shù)是NULL,就標(biāo)記resnull為true goto strictfail; } } fcinfo->isnull = false; d = op->d.func.fn_addr(fcinfo); *op->resvalue = d; *op->resnull = fcinfo->isnull; strictfail: EEO_NEXT(); } ... EEO_CASE(EEOP_ASSIGN_TMP_MAKE_RO) { int resultnum = op->d.assign_tmp.resultnum; //上一步的resnull值傳遞到resultslot中,標(biāo)記該slot是一個(gè)NULL resultslot->tts_isnull[resultnum] = state->resnull; if (!resultslot->tts_isnull[resultnum]) resultslot->tts_values[resultnum] = MakeExpandedObjectReadOnlyInternal(state->resvalue); else resultslot->tts_values[resultnum] = state->resvalue; EEO_NEXT(); }
這樣就完成了NULL值相關(guān)的加法計(jì)算。
總結(jié)
到此這篇關(guān)于postgresql處理空值NULL與替換的問(wèn)題解決辦法的文章就介紹到這了,更多相關(guān)postgresql空值NULL與替換處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PostgreSQL數(shù)據(jù)庫(kù)中修改表字段的常用命令小結(jié)
這篇文章主要給大家介紹了PostgreSQL數(shù)據(jù)庫(kù)中修改表字段的常用命令操作,文中有詳細(xì)的代碼示例供大家參考,具有一定的參考價(jià)值,需要的朋友可以參考下2023-12-12PostgreSQL使用MySQL作為外部表(mysql_fdw)
PostgreSQL 提供了一種訪(fǎng)問(wèn)和操作外部數(shù)據(jù)源的機(jī)制,稱(chēng)為外部數(shù)據(jù)包裝器,本文主要給大家介紹了PostgreSQL使用MySQL作為外部表的方法,感興趣的朋友跟隨小編一起看看吧2022-11-11PostgreSQL模式匹配與正則表達(dá)式方法總結(jié)
在postgresql中使用正則表達(dá)式時(shí)需要使用關(guān)鍵字“~”,以表示該關(guān)鍵字之前的內(nèi)容需匹配之后的正則表達(dá)式,這篇文章主要給大家介紹了關(guān)于PostgreSQL模式匹配與正則表達(dá)式的相關(guān)資料,需要的朋友可以參考下2022-11-11Linux 上 定時(shí)備份postgresql 數(shù)據(jù)庫(kù)的方法
這篇文章主要介紹了Linux 上 定時(shí)備份postgresql 數(shù)據(jù)庫(kù)的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02Postgresql 實(shí)現(xiàn)查詢(xún)一個(gè)表/所有表的所有列名
這篇文章主要介紹了Postgresql 實(shí)現(xiàn)查詢(xún)一個(gè)表/所有表的所有列名,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12SpringBoot3集成PostgreSQL的詳細(xì)過(guò)程
PostgreSQL是一個(gè)功能強(qiáng)大的開(kāi)源數(shù)據(jù)庫(kù)系統(tǒng),具有可靠性、穩(wěn)定性、數(shù)據(jù)一致性等特點(diǎn),且可以運(yùn)行在所有主流操作系統(tǒng)上,包括Linux、Unix、Windows等,這篇文章主要介紹了SpringBoot3集成PostgreSQL,需要的朋友可以參考下2024-03-03