5

我有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(*)在这里添加 a 无济于事,我完全不知道如何在过滤后计算记录。

4

3 回答 3

13

有一种非常简单的方法可能对您有用:

select count(distinct ifnull(f, id))
from a

请注意,此查询假定 f 值绝不是 id 值,并且根据样本数据和经验,这是合理的。

编辑:

我想了想,还有一个更简单的方法:

select count(distinct f) + sum(f is null) from a;

你可以看到在 sqlfiddle 上运行

这是有效的,因为distinct丢弃空值,并sum(condition)计算条件为 true 的次数,因为在 mysql 中 true is1和 false is 0

于 2012-11-28T13:18:09.760 回答
4

NOT EXISTSWHERE子句中使用:

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值,而您想要

每个记录 WHERE f 为 NULL。

于 2012-11-28T12:51:56.737 回答
0
    UPDATE comments SET view =     
                              (SELECT COUNT(DISTINCT browser, ip, ifnull(user_id, 0)) 
                              FROM counters WHERE item_type=comments.item_type )
    WHERE id=1
于 2016-05-18T14:16:58.733 回答