postgresql处理空值NULL与替换的问题解决办法
作者:Austindatabases
开头还是介绍一下群,如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请加微信liuaustin3 ,(共1140人左右 1 + 2 + 3)新人会进入3群
最近一直在研究关于POSTGRESQL 开发方面的一些技巧和问题,本期是关于在开发中的一些关于NULL 值处理的问题。在业务开发中,经常会遇到输入的值为NULL 但是实际上我们需要代入默认值的问题,而通常的处理方法是,在字段加入默认值设置,让不输入的情况下,替换NULL值,同时还具备另一个字段类型转换的功能。
1 默认值取代NULL
2 处理程序可选字段的值为空的情况
3 数据转换和类型的转换
下面我们看看如何进行实际中的相关事例
事例1 程序中在需要两个字段进行计算后,得出结果进行展示,比如买一送一,或买一送二 等,我们先创建一个表
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;
在上图中,我们可以看到由于打折的数字是没有的,而在查询中导致由于部分商品在购买中没有打折,而导致最后付款的实际钱数为0。在这样的情况下,那么在这样的情况下,我们可以使用POSTGRESQL 提供的函数来解决这个问题。
这里采用了coalesce 函数,在 sell_discount 为NULL的情况下,则我们用1来替代这个值,保证最终计算的逻辑结果是正确的。
实际上,如果在设计表的时候,给这个字段的默认值为1 ,也可以解决这个问题,但是如果早期未做处理,上线后数据量较大,也可以用coalesce 来解决这个问题,并且使用这个函数是灵活的,后面NULL 可以替代的值也是你可以随意指定的。
问题2 在一个程序逻辑中,有三个字段,但是其中只能有一个字段可以被展示,其他的字段的值为NULL,比如一个猜盒子里面有什么的程序,盒子里面有什么是一个已经预定好的情况,并且在开奖的时候,需要给出到底那个盒子里面有奖品。
我们在建立这样一个表
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 函数有什么办法来进行操作吗?
我们再来看
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 还可以针对某些字段的类型进行转换,如日期类型转换为文字的需求。
如我们在日期里面是NULL 的情况下,我们不想展示为NULL,而是展示的
时候,为我们想用其他的文字来代替它。
select id, COALESCE(CAST(date_time AS TEXT), 'date_time') AS date_time from guess_what;
a
上面的例子就是我们在针对date_time 字段时间类型的数据在他是NULL的情况下,展示出来我们指定的其他类型的文字,相关的写法如上。COALESCE可以与其他条件逻辑(如CASE)结合使用,这基于特定条件或标准对NULL值进行更复杂的处理。通过利用COALESCE的灵活性并将其与条件逻辑相结合,您可以实现更复杂的数据转换和替换。
附:PG的空值相加如何实现
PostgreSQL数据库中,对于NULL值相加的处理:任何数值和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 行记录)
看下加的结果:
postgres=# select id1+id2 from t3;
?column?
----------
3
(4 行记录)
可以看到只要有一个参数是NULL,那么加的结果就是NULL。那么这个计算是如何实现的呢?
从前文可以了解到操作符“+”的实现机制,真正执行是在ExecInterpExpr函数中:
ExecInterpExpr EEO_CASE(EEOP_FUNCEXPR_STRICT)//操作符函数的执行 { 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;//只要有一个参数是NULL,就标记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中,标记该slot是一个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值相关的加法计算。
总结
到此这篇关于postgresql处理空值NULL与替换的问题解决办法的文章就介绍到这了,更多相关postgresql空值NULL与替换处理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!