postgresql处理空值NULL与替换的问题解决办法

 更新时间:2024年02月06日 10:57:14   作者:Austindatabases  
由于在不同的语言中对空值的处理方式不同,因此常常会对空值产生一些混淆,下面这篇文章主要给大家介绍了关于postgresql处理空值NULL与替换的问题解决办法,需要的朋友可以参考下

开头还是介绍一下群,如果感兴趣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与替换处理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • CentOS中运行PostgreSQL需要修改的内核参数及配置脚本分享

    CentOS中运行PostgreSQL需要修改的内核参数及配置脚本分享

    这篇文章主要介绍了CentOS中运行PostgreSQL需要修改的内核参数及配置脚本分享,本文从系统资源限制类和内存参数优化类来进行说明,需要的朋友可以参考下
    2014-07-07
  • postgresql如何兼容MySQL if函数

    postgresql如何兼容MySQL if函数

    这篇文章主要介绍了postgresql如何兼容MySQL if函数问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • PostgreSQL中的日期/时间函数详解

    PostgreSQL中的日期/时间函数详解

    这篇文章主要给大家介绍了关于PostgreSQL中日期/时间函数的相关资料,文章通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-01-01
  • PostgreSQL limit的神奇作用详解

    PostgreSQL limit的神奇作用详解

    这篇文章主要介绍了PostgreSQL limit的神奇作用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-09-09
  • Windows下Postgresql数据库的下载与配置方法

    Windows下Postgresql数据库的下载与配置方法

    这篇文章主要介绍了Windows下Postgresql数据库的下载与配置方法 ,需要的朋友可以参考下
    2014-06-06
  • PostgreSQL function返回多行的操作

    PostgreSQL function返回多行的操作

    这篇文章主要介绍了PostgreSQL function返回多行的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • postgres 使用存储过程批量插入数据的操作

    postgres 使用存储过程批量插入数据的操作

    这篇文章主要介绍了postgres 使用存储过程批量插入数据的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • postgresql synchronous_commit参数的用法介绍

    postgresql synchronous_commit参数的用法介绍

    这篇文章主要介绍了postgresql synchronous_commit参数的用法介绍,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Postgresql数据库角色创建登录详解

    Postgresql数据库角色创建登录详解

    这篇文章主要为大家介绍了Postgresql数据库角色创建登录详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • PostgreSQL ROW_NUMBER() OVER()的用法说明

    PostgreSQL ROW_NUMBER() OVER()的用法说明

    这篇文章主要介绍了PostgreSQL ROW_NUMBER() OVER()的用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02

最新评论