PostgreSQL 如何将 null 视为一个值

PostgreSQL how to treat null as a value

让我们说:

  1. 我有一个名为“movie”的 table,它包含一个名为“categoryid”的字段,该字段指向另一个“类别”table。

  2. 如果电影没有 select 类别,字段“categoryid”可以为空。否则它是一个数字。

  3. 我有一个电影搜索页面的用户界面,它以复选框列表的形式列出所有类别,因此用户可以 select 多个类别。此复选框列表还包括 select 电影的“未分类”选项,其中“categoryid”为空

现在用户正在 select 设置 null 和多个其他复选框,这反映在 SQL 代码中,看起来像这样:

SELECT * FROM movie WHERE categoryid in (1, 5, 9, NULL);

显然,上面的代码不起作用。我猜 null 没有像在其他语言中那样被视为 SQL 值!过滤掉未分类的电影。但是下面的代码有效

SELECT * FROM movie WHERE categoryid IN (1, 5, 9) OR categoryid IS NULL;

但不幸的是,我使用的框架无法进行此例外处理,而且我对数据库的结构没有灵活性,因为它是由其他软件生成的。那么,有什么办法可以将 NULL 值与 IN 运算符一起使用吗?或任何其他接受允许值列表的运算符?

不幸的是,

IN 不适用于 NULL 值。另一种方法是将值放在派生的 table 中,然后使用 IS NOT DISTINCT FROM:

select m.*
from movie m
inner join (values (1), (5), (9), (null)) v(val) 
    on v.val is not distinct from m.category_id

您的应用程序将值列表作为数组传递可能更方便:

select m.*
from movie m
inner join unnest(array[1, 5, 9, null]) v(val)
    on v.val is not distinct from m.category_id

我的建议是不要为此使用 NULL。如果您将 NULL 解释为“未知”,则 NULL 效果最好,但在您的情况下,该值是已知的:它是“未分类”。

因此,最好为此创建一个特殊类别并像处理所有其他类别一样处理它。这里不允许NULL,一切都变得简单。

或者,您可以使用类似

的方法将 NULL 替换为查询中不存在的值
coalesce(category, '')

这将即时创建“未分类”类别。

具有相同结果的另一种方法是:

SELECT * FROM movie WHERE zeroifnull(categoryid) in (1, 5, 9, 0);

背后的想法是预先将您的 NULL 值转换为另一个值(在本例中为零)。

您也可以使用 IFNULL()。