91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

mysql踩坑之count?distinct多列問題怎么解決

發布時間:2023-03-23 10:18:31 來源:億速云 閱讀:151 作者:iii 欄目:開發技術

這篇文章主要介紹“mysql踩坑之count distinct多列問題怎么解決”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“mysql踩坑之count distinct多列問題怎么解決”文章能幫助大家解決問題。

復現的測試數據庫如下所示:

CREATE TABLE `test_distinct` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
  `b` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

表內測試數據如下,現在我們需要統計這三列去重后的列的數量。

mysql踩坑之count?distinct多列問題怎么解決

問題分析

小伙伴給了我四條用來定位問題的查詢語句

SELECT COUNT(*) AS cnt FROM test_distinct;
SELECT COUNT(DISTINCT id, a, b) as cnt FROM test_distinct;
SELECT id, a, b, COUNT(*) AS cnt FROM test_distinct GROUP BY id, a, b HAVING cnt > 1;
SELECT 
	l.id AS l_id,
	l.a AS l_a,
	l.b AS l_b,
	r.id AS r_id,
	r.a AS r_a,
	r.b AS r_b
FROM test_distinct l LEFT JOIN test_distinct r
ON l.id = r.id AND l.a = r.a AND l.b = r.b
WHERE r.id is NULL or r.id = 'null';

查詢結果,如下所示:

mysql踩坑之count?distinct多列問題怎么解決

mysql踩坑之count?distinct多列問題怎么解決

mysql踩坑之count?distinct多列問題怎么解決

mysql踩坑之count?distinct多列問題怎么解決

注意!!!從測試數據很快就能大概猜出問題在哪,但是原來表中數據是有3萬多條,無法用肉眼查看數據。

上面查詢結果違反直覺的點有兩個:

  • 第二條去重統計后數據少了一條,但是,第三條數據的結果顯示并沒有相同的數據。

  • 用同一張表做左外連接出現了驅動表有數據,而被驅動表為空的情況。

先看第二個問題,官方文檔上有如下解釋:

  • 與ON一起使用的search_condition和WHERE子句中使用的條件表達式一樣。 通常,ON子句用于指定如何連接表的條件,WHERE子句限制要包含在結果集中的行。

  • 如果對于LEFT JOIN中ON或USING部分中的條件,右表沒有匹配的行,則右表使用所有列設置為NULL。

  • 不能使用算術比較運算符(如=,<或<>)來比較NULL。

SELECT NULL = NULL;
SELECT NULL IS NULL;

mysql踩坑之count?distinct多列問題怎么解決

mysql踩坑之count?distinct多列問題怎么解決

所以問題二在于NULL=NULL的結果永遠為False,也就導致兩行原本相等的數據結果卻不相等。

可是這并沒有解決第一個問題:為什么去重后有一條數據消失了。但是,我們可以猜測消失的數據很有可能和NULL值有關系。

我們將count和distinct兩個操作分開:

SELECT COUNT(*) as cnt FROM (SELECT  DISTINCT id, a, b FROM test_distinct) as tmp;

mysql踩坑之count?distinct多列問題怎么解決

嗯?結果是正確的,那就說明count(distinct expr)生成的查詢計劃可能和我們想象的不一樣,并不是先去重再統計,使用explain分析一下兩條語句的查詢計劃,如下所示:

mysql踩坑之count?distinct多列問題怎么解決

mysql踩坑之count?distinct多列問題怎么解決

從表中可以看到,mysql執行引擎直接將count(distinct expr)作為一個查詢,查看官方文檔:

mysql踩坑之count?distinct多列問題怎么解決

解決辦法

至此問題才終于弄清楚了。解決這個問題的辦法有兩種,第一種就是上述的先去重后統計,第二種可以利用IFNULL()函數:

SELECT COUNT(DISTINCT id, a, IFNULL(b, '0')) as cnt FROM test_distinct;

另外補充一點,count()嘚瑟使用:

SELECT id, a, b, COUNT(*) FROM test_distinct GROUP BY id, a, b;
SELECT id, a, b, COUNT(b) FROM test_distinct GROUP BY id, a, b;

mysql踩坑之count?distinct多列問題怎么解決

mysql踩坑之count?distinct多列問題怎么解決

知識點

  • 不能使用算術比較運算符(如=,<或<>)來比較空值;

  • count(distinct expr)返回expr列中不同的且非空的行數;

  • COUNT()有兩個非常不同的作用:它可以統計某個列值的數量,也可以統計行數。在統計列值時要求列值是非空的(不統計NULL)。如果在COUNT()的括號中定了列或者列表達式,則統計的就是這個表達式有值的結果數。COUNT()的另一個作用是統計結果集的行數。當MySQL確認括號內的表達式值不可能為空時,實際上就是在統計行數。最簡單的就是當我們使用COUNT()的時候,這種情況下通配符并不像我們猜想的那樣擴展成所有的列,實際上,他會忽略所有列而直接統計所有的行數&mdash;&mdash;《高性能MySQL》;

  • 在InnoDB中,SELECT COUNT(*)和SELECT COUNT(1)處理方式一樣, 沒有性能差異。

關于“mysql踩坑之count distinct多列問題怎么解決”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

嘉黎县| 金平| 西和县| 文安县| 门源| 白朗县| 伊宁市| 会泽县| 都匀市| 卫辉市| 门源| 元阳县| 莱芜市| 浦东新区| 中卫市| 胶州市| 道孚县| 西乌| 新巴尔虎左旗| 合作市| 盐津县| 阜康市| 巴马| 灵台县| 台北市| 卓尼县| 页游| 娱乐| 西贡区| 梓潼县| 邵阳县| 平和县| 长阳| 顺昌县| 星座| 乐至县| 丰镇市| 井研县| 新巴尔虎左旗| 崇礼县| 全州县|