2011-08-05 54 views
3

我已经按字段daynumber对表格进行了分区。在白天我写入这个表格日志,然后计算一些统计数据。桌子很大,每天我都有〜3M新的排。该字段myField被编入索引。与DISTINCT不一致COUNT

这个查询

SELECT COUNT(DISTINCT myField) FROM mytable WHERE daynumber=somevalue; 

返回0,这是一个错误。

这个查询

SELECT COUNT(*) FROM (SELECT DISTINCT(myField) FROM mytable WHERE daynumber=somevalue) t; 

返回正确的值。

对于某些daynumber值,第一个查询正常工作。我试图重复那个分区,但没有任何效果。有什么建议么?


更新

表方案看起来像

CREATE TABLE `mytable` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `daynumber` INT(10) UNSIGNED NOT NULL, 
    `myField` VARCHAR(1024) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, 
    ... other fields 
    PRIMARY KEY (`daynumber`,`id`), 
    KEY `myField` (`myField`(20)) 
) ENGINE=MYISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC 
PARTITION BY LIST (daynumber) 
(PARTITION day_810 VALUES IN (810) ENGINE = MyISAM, 
PARTITION day_811 VALUES IN (811) ENGINE = MyISAM, 
PARTITION day_812 VALUES IN (812) ENGINE = MyISAM 
....) 

回答

4

这是因为你myfield包含NULL

SELECT COUNT(DISTINCT coalesce(myField, '')) 
FROM mytable WHERE daynumber=somevalue; 

​​3210有几分转换NULL''
可能不是你问什么,但将返回正确的计数(仍然)

+0

+1查询不能是不一致的。空可以做一些时髦的东西。我的建议是将字段设置为不可为空,如果您打算将它们用于累计总数等。 – Spudley

2

让说

  • 你匹配4行的daynumber = someValue中
  • MyField的这3行是1, 2, 2, NULL

所以,子查询有2个步骤。

  • SELECT DISTINCT(myField)给出了3行:1, 2, NULL
  • SELECT COUNT(*)给3。

没有子查询,一个步骤

  • SELECT COUNT(DISTINCT(myField))计数仅1, 2 = 2

原因:

  • COUNT(*)包括空值
  • COUNT(anythingelse)不凑NT NULL值

,因为他们是不同的查询

它我记得最好的讨论是DBA.SE: What is the difference between select count(*) and select count(any_non_null_col)?

+0

+1我对此做了一些测试,它是正确的答案。 – nobody

+1

因此,如果“SELECT COUNT(DISTINCT myField)FROM mytable WHERE daynumber = somevalue;”返回0,这意味着在表中没有非空值?但我有非空值 – antony

+0

@antony:什么'SELECT DISTINCT(myField)FROM mytable WHERE daynumber = somevalue'给你? – gbn