count(distinct column_name) 是统计某列不重复值最直接的方法,它自动忽略 null 值,适用于大多数去重计数场景;对于多列组合的不重复统计,可通过 group by 分组后计数或使用带分隔符的 concat 拼接避免歧义;若需将 null 视为独立值,可结合 coalesce 函数将其替换为唯一标识;在性能方面,为统计列创建索引可大幅提升查询效率,而对超大数据集可采用近似计数或物化视图预聚合;条件性不重复统计则可通过 where 子句筛选或在 count(distinct) 中嵌套 case when 实现多维度分析,这些方法共同构成了 sql 中完整且灵活的不重复值统计解决方案。

COUNT(DISTINCT column_name)
在SQL中,统计不重复值最核心、最直接的手段就是使用
COUNT(DISTINCT expression)
比如,你有一张
orders
SELECT COUNT(DISTINCT customer_id) FROM orders;
这条语句会遍历
orders
customer_id
customer_id
COUNT(DISTINCT)
NULL
customer_id
NULL
更复杂一点,如果你想知道某个产品有多少独特的销售渠道,假设
sales
product_id
channel
SELECT product_id, COUNT(DISTINCT channel) FROM sales GROUP BY product_id;
这会列出每个
product_id
COUNT(DISTINCT)
当然,
COUNT(DISTINCT)
一个常见的替代方案是结合
DISTINCT
SELECT COUNT(*)
FROM (
SELECT DISTINCT customer_id
FROM orders
) AS unique_customers;这种写法先用
SELECT DISTINCT customer_id
customer_id
COUNT(*)
COUNT(DISTINCT customer_id)
另外,
GROUP BY
customer_id
GROUP BY
SELECT customer_id, COUNT(*) FROM orders GROUP BY customer_id;
如果你只是想知道不重复值的总数,那么可以这样:
SELECT COUNT(customer_id)
FROM (
SELECT customer_id
FROM orders
GROUP BY customer_id
) AS grouped_customers;这种方式先通过
GROUP BY
customer_id
COUNT(DISTINCT)
处理不重复值统计,特别是遇到NULL值和大数据量时的性能,是实际工作中常常会遇到的挑战。
NULL值的处理: 前面提到了,
COUNT(DISTINCT column_name)
NULL
customer_id
NULL
NULL
但万一你的业务场景要求把
NULL
feedback_type
NULL
NULL
COUNT(DISTINCT feedback_type)
这时候,一个实用的技巧是使用
COALESCE
NULL
COUNT(DISTINCT)
SELECT COUNT(DISTINCT COALESCE(feedback_type, 'NO_FEEDBACK_TYPE_SPECIFIED')) FROM feedbacks;
这样,
'NO_FEEDBACK_TYPE_SPECIFIED'
性能问题: 当表的数据量非常大时,
COUNT(DISTINCT)
索引的魔力: 最直接、最有效的优化手段,就是为你要统计的列创建索引。例如:
CREATE INDEX idx_customer_id ON orders (customer_id);
一个合适的索引能极大加速数据库查找和排序唯一值的过程。我亲身经历过,给一个几亿行的表加上索引后,原本几分钟的
COUNT(DISTINCT)
大数据量的近似计数: 对于一些对精确度要求不那么高的场景,或者数据量实在太大,精确计数成本过高时,一些数据库提供了近似计数的功能(比如PostgreSQL的HyperLogLog扩展,或者某些数据仓库服务中的近似函数)。这些函数能以极低的资源消耗,给出非常接近真实值的估计。虽然这超出了标准SQL的范畴,但了解有这种技术存在,能拓宽解决问题的思路。
数据预聚合/物化视图: 如果某个不重复值统计是高频操作,并且数据变化不频繁,那么可以考虑创建物化视图(Materialized View)或定期将统计结果存入一张汇总表。这样,后续的查询直接从预计算好的结果中获取,效率自然最高。这就像把一份经常要查的报告提前打印出来,而不是每次都现场计算。
在实际的数据分析中,我们经常需要统计的不是单列的不重复值,而是多列组合的唯一性,或者在特定条件下才进行不重复计数。
统计多列组合的不重复值: 假设你想知道有多少对独特的“客户-产品”购买记录,也就是说,有多少个客户购买了多少种特定的产品组合。简单的
COUNT(DISTINCT customer_id)
customer_id
product_id
最标准且跨数据库兼容的方法是使用
GROUP BY
SELECT COUNT(*)
FROM (
SELECT customer_id, product_id
FROM orders
GROUP BY customer_id, product_id
) AS unique_customer_product_pairs;这个查询会先根据
customer_id
product_id
COUNT(*)
在某些数据库(如PostgreSQL),你也可以尝试
COUNT(DISTINCT (column1, column2))
DISTINCT
GROUP BY
另一种思路是,如果你确定组合后的字符串不会出现歧义,可以使用字符串拼接:
SELECT COUNT(DISTINCT CONCAT(customer_id, '-', product_id)) FROM orders;
这种方法简单粗暴,但要注意
CONCAT
CONCAT('1', '23')CONCAT('12', '3')'123'
-
_
特定条件下的不重复值统计: 有时候,我们只关心满足特定条件的不重复值。例如,只想统计“活跃用户”中的不重复
user_id
product_id
最直接的方法是结合
WHERE
SELECT COUNT(DISTINCT user_id) FROM users WHERE status = 'active';
这会先筛选出所有
status
user_id
更灵活一点,如果你想在一个查询中同时统计多个条件下的不重复值,或者在
COUNT(DISTINCT)
CASE WHEN
SELECT
COUNT(DISTINCT CASE WHEN order_date BETWEEN '2023-01-01' AND '2023-01-31' THEN customer_id END) AS distinct_customers_jan_2023,
COUNT(DISTINCT CASE WHEN order_amount > 1000 THEN customer_id END) AS distinct_high_value_customers
FROM orders;这里,
CASE WHEN
customer_id
NULL
COUNT(DISTINCT)
NULL
以上就是sql怎样使用count(distinct)统计不重复值 sql不重复值统计的实用操作方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号