我有两个字段的表a
:id
(PK)和f
。
请考虑以下记录:
id | f
1 | NULL
2 | 'foo'
3 | 'bar'
4 | NULL
5 | 'foo'
6 | 'baz'
我想检索和计算具有不同f
值的所有记录,包括每条记录WHERE f IS NULL
。给定此条件,查询应返回除 #5 之外的所有记录,因为集合中已包含相同的值,并且总数将为 5。
我用来检索所有记录的查询如下所示:
SELECT CASE WHEN EXISTS (SELECT id FROM a a2 WHERE a2.f = a.f AND a.id < a2.id) THEN 1 END AS not_distinct FROM a HAVING not_distinct IS NULL
如果此查询可以改进,我欢迎任何反馈。无论如何,主要问题是计数。显然,添加COUNT(*)
在这里无济于事,我完全不知道过滤后如何计算记录。
有一种非常简单的方法可能适合您:
select count(distinct ifnull(f, id))
from a
请注意,此查询假定 f 值从来都不是 id 值,根据示例数据和经验,这是合理的。
编辑:
我想了想,还有一个更简单的方法:
select count(distinct f) + sum(f is null) from a;
你可以看到在SQLfiddle上运行
这是有效的,因为distinct
丢弃了空值,并且sum(condition)
计算条件为真的次数,因为在 mysql 中,真是1
而假是0
。
在WHERE
子句中使用NOT EXISTS
:
SELECT count(*)
FROM a
WHERE NOT EXISTS (SELECT * FROM a a2 WHERE a2.f = a.f AND a2.id < a.id);
这样,您还可以获得实际行 - 如果您需要的行数超过裸计数:
SELECT *
FROM a
WHERE NOT EXISTS (SELECT * FROM a a2 WHERE a2.f = a.f AND a2.id < a.id)
=
运算符确保包含所有带有f IS NULL
的行。您的查询中已经有了这个。
-> sqlfiddle
这些都不起作用:
SELECT DISTINCT f FROM a;
SELECT * FROM a GROUP BY f;
.. 因为两者都会折叠NULL
值,而你想要
其中 F 为空的每条记录。
UPDATE comments SET view =
(SELECT COUNT(DISTINCT browser, ip, ifnull(user_id, 0))
FROM counters WHERE item_type=comments.item_type )
WHERE id=1