2011-08-05 77 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