PostgreSQL 如何将 null 视为一个值
PostgreSQL how to treat null as a value
让我们说:
我有一个名为“movie”的 table,它包含一个名为“categoryid”的字段,该字段指向另一个“类别”table。
如果电影没有 select 类别,字段“categoryid”可以为空。否则它是一个数字。
我有一个电影搜索页面的用户界面,它以复选框列表的形式列出所有类别,因此用户可以 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()。
让我们说:
我有一个名为“movie”的 table,它包含一个名为“categoryid”的字段,该字段指向另一个“类别”table。
如果电影没有 select 类别,字段“categoryid”可以为空。否则它是一个数字。
我有一个电影搜索页面的用户界面,它以复选框列表的形式列出所有类别,因此用户可以 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()。