0

我有一个表用户,其中有 6,169。其中一些用户在名为“status”的列中被标记为过期用户,其余用户在该列中的值为 NULL。我正在尝试为所有仍处于活动状态且值为“活动”的用户更新“状态”列,但是我无法准确选择要更新的组。

当我跑

SELECT COUNT(id) FROM users;

它确认了 6,169 个用户数。

当我跑

SELECT COUNT(id) FROM users WHERE status='expired'

它确认了 2,500 个过期用户。但是,当我跑步时

SELECT COUNT(id) FROM users WHERE status !='expired'

我得到计数​​ 0。我尝试过类似的变化

SELECT COUNT(id) FROM users WHERE NOT status='expired'

并查看了许多其他 StackOverflow 问题,但无法弄清楚为什么我的语法不正确。任何帮助将非常感激!

4

5 回答 5

2

状态可能是一个可以为空的列,并且NULL != 'expired'永远不会是真的。

你可以试试这个:

SELECT COUNT(id) FROM users WHERE status IS NULL

它应该返回 3696。请在此处查看小提琴。

于 2013-08-06T20:49:20.073 回答
1

正如您在问题中提到的,该status列具有NULL值。对值的任何比较(除了is null)都NULL返回NULL。并且,NULL被认为是假的。您可以将其视为“未知”而不是“缺失”,因为这有助于逻辑。

正如您所发现的,一个NULL值在所有这些方面都失败了:

where status = 'expired'
where status <> 'expired'
where not status = 'expired'
where not status <> 'expired'
where status = NULL
where status != NULL

请记住:比较是NULL,而不是“假”。因此,“NOT NULL”仍然是 NULL(因为不是未知的布尔值仍然是未知的)。相比之下,“不假”将是真的。

唯一通过的直接比较是:

where status is NULL

要获得活动,您需要:

SELECT COUNT(id)
FROM users
WHERE status <> 'expired' or status is NULL

或者,或者,使用coalesce()

SELECT COUNT(id)
FROM users
WHERE coalesce(status, 'active') <> 'expired';

后者更容易阅读。如果有可用的索引,以前的版本更有可能使用索引。

于 2013-08-06T21:03:44.693 回答
0

选择所有过期用户....

SELECT COUNT(id) FROM users WHERE status = 'expired'

选择所有活跃用户...

SELECT COUNT(id) FROM users WHERE status IS NULL;
于 2013-08-06T20:50:22.330 回答
0

你可以反过来做

SELECT COUNT(id) FROM users 
WHERE id not in (SELECT id FROM users WHERE status='expired')
于 2013-08-06T20:52:13.897 回答
0

可能尝试

SELECT COUNT(id) FROM users WHERE status NOT IN ('expired')

或者

SELECT COUNT(id) FROM users WHERE status <> 'expired'

反而?通常我会在列是数字值时执行这些操作,我不确定它是否适用于字符串值。

于 2013-08-06T20:53:00.300 回答