以时间为跨度统计不同的值,在该时间出现的次数。
创新互联-专业网站定制、快速模板网站建设、高性价比平阳网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式平阳网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖平阳地区。费用合理售后完善,十年实体公司更值得信赖。
语言如下:
select count(*),'列名' from tablename group by '列名'
select count(*),a_yqm from user group by a_yqm
举例:
这里,我要查询出1年内每个月份periods字段不同值的次数。
比如下图中可见的2015-4月,periods为2出现了3次,3出现了1次,最关键的是 periods你不知道有多少种可能的值,也许这个月有1,也许没有。
CREATE TABLE person (
name varchar(20)
);
INSERT INTO person VALUES ('a,b,c');
INSERT INTO person VALUES ('a,b');
INSERT INTO person VALUES ('a,c');
DELIMITER //
DROP FUNCTION GetTextCount //
/**********
-- 获取字符串中有几个部分.
**********/
CREATE FUNCTION GetTextCount(pSourceText VARCHAR(255), pDivChar CHAR(1))
RETURNS TINYINT
BEGIN
-- 预期结果.
DECLARE vResult TINYINT;
-- 当前逗号的位置.
DECLARE vIndex INT;
-- 前一个逗号的位置.
DECLARE vPrevIndex INT;
-- 结果的初始值.
SET vResult = 1;
-- 查询第一个 逗号的位置.
SET vIndex = INSTR(pSourceText, pDivChar);
IF vIndex = 0 THEN
-- 参数中没有逗号,直接返回.
RETURN vResult;
END IF;
-- 初始化情况,前一个逗号不存在.
SET vPrevIndex = 0;
-- 循环处理。
WHILE vIndex 0 DO
-- 结果递增.
SET vResult = vResult + 1;
-- 前一个逗号的位置 = 当前逗号的位置
SET vPrevIndex = vIndex;
-- 查询下一个逗号的位置.
SET vIndex = LOCATE(pDivChar, pSourceText, vPrevIndex + 1);
END WHILE;
-- 返回结果.
RETURN vResult;
END;
//
DROP FUNCTION GetTextValue //
/**********
-- 获取字符串中具体某一个部分的数据.
**********/
CREATE FUNCTION GetTextValue(pSourceText VARCHAR(255), pDivChar CHAR(1), pIndex TINYINT)
RETURNS VARCHAR(255)
BEGIN
-- 预期结果.
DECLARE vResult VARCHAR(255);
IF pIndex = 1 THEN
SELECT SUBSTRING_INDEX(pSourceText, pDivChar, 1) INTO vResult;
ELSE
SELECT
REPLACE(
SUBSTRING_INDEX(pSourceText, pDivChar, pIndex),
CONCAT(SUBSTRING_INDEX(pSourceText, pDivChar, pIndex - 1) , pDivChar),
'') INTO vResult;
END IF;
-- 返回.
RETURN vResult;
END;
//
DELIMITER ;
SELECT
GetTextValue(t.name, ',', MaxNum.No) AS `名称`,
COUNT(*) AS `个数`
FROM
person t,
(SELECT 1 No UNION ALL
SELECT 2 No UNION ALL
SELECT 3 No UNION ALL
SELECT 4 No UNION ALL
SELECT 5 No ) MaxNum
WHERE
GetTextCount(t.name, ',') = MaxNum.No
GROUP BY
GetTextValue(t.name, ',', MaxNum.No);
+------+------+
| 名称 | 个数 |
+------+------+
| a | 3 |
| b | 2 |
| c | 2 |
+------+------+
3 rows in set (0.01 sec)
表统计信息是数据库基于成本的优化器最重要的参考信息;统计信息不准确,优化器可能给出不够优化的执行计划或者是错误的执行计划。对统计信息的计算分为非持久化统计信息(实时计算)与持久化统计信息。
非持久化统计信息
统计信息没有保存在磁盘上,而是频繁的实时计算统计信息;
每次对表的访问都会重新计算其统计信息;
假设针对一张大表的频繁查询,那么每次都要重新计算统计信息,很耗费资源。
持久化统计信息
把一张表在某一时刻的统计信息值保存在磁盘上;
避免每次查询时重新计算;
如果表更新不是很频繁,或者没有达到 MySQL 必须重新计算统计信息的临界值,可直接从磁盘上获取;
即使 MySQL 服务重启,也可以快速的获取统计信息值;
统计信息的持久化可以针对全局设置也可以针对单表设置。
接下来,详细说 MySQL 统计信息如何计算,何时计算,效果评估等问题。在 MySQL Server 层来控制是否自动计算统计信息的分布,并且来决策是持久化还是非持久化。
2020-03-01
对于count的函数的使用,我们常见的一个错误是在括号内随意指定一个列去统计结果集的行数。但只有指定的行确实都是有值的时候,统计的才是实际的行数,否则可能统计的结果并不是实际的行数。而对于MyISAM存储引擎,如果某一列的值确实不可能为null时,MySQL内部就会将count()函数优化成count(*),若没有带where条件,此时计算速度是非常快的,因为此时没有实际的去计算表的行数。
总结: 对于MyISAM存储引擎,不带where条件的count(*)是非常快的。
技巧:
利用上述MyISAM的count(* )特性,加速一些特定查询条件的count()查询。
如:
对于select count(* ) from tablename where id 10; 可以做如下的反转查询:
select (select count(* ) from tablename) - count(* ) from tablename where id 10;
因为这样在查询阶段MySQL将子查询当做一个常数来处理,大大减少了扫描的行数。
CREATE function [dbo].[GetCharIndexNum](@findstring varchar(max),@string varchar(max))
returns int
AS
BEGIN
declare @location int , --要找的字符位置
@num int --要找的字符出现的次数
set @num =0
set @location = charindex (@findstring,@string)
while @location 0 ---字符串中存在要找的字符
begin
set @num =@num +1
set @string =substring(@string,@location+1,len(@string))
set @location = charindex (@findstring,@string)
end
return @num
END
--举个例子调用这个标量值函数 select [dbo].[GetCharIndexNum]('5','abc5ab5')
返回值2,5这个字符出现了2次