You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL统计逗号分隔字段时如何去重计算总数量

问题原因

你当前使用的统计语句仅累加了每行room_id字段拆分后的元素总数,没有对全局重复的room_id做去重处理,所以示例数据中重复出现的4被计数了2次,最终得到错误结果5。

方案1:MySQL 8.0及以上版本(推荐)

使用递归CTE拆分所有room_id为单行数据后去重计数:

WITH RECURSIVE split_rooms AS (
    SELECT 
        id,
        TRIM(room_id) AS room_str,
        LOCATE(',', room_id) AS comma_pos
    FROM booking
    UNION ALL
    SELECT 
        id,
        TRIM(SUBSTRING(room_str, comma_pos + 1)),
        LOCATE(',', SUBSTRING(room_str, comma_pos + 1))
    FROM split_rooms
    WHERE comma_pos > 0
)
SELECT COUNT(DISTINCT TRIM(SUBSTRING_INDEX(room_str, ',', 1))) AS total
FROM split_rooms;

如果是MySQL 8.0.19及以上版本,还可以用JSON_TABLE更简便地实现:

SELECT COUNT(DISTINCT TRIM(room_id_val)) AS total
FROM booking,
JSON_TABLE(
    CONCAT('["', REPLACE(room_id, ',', '","'), '"]'),
    '$[*]' COLUMNS (room_id_val VARCHAR(255) PATH '$')
) AS t;

方案2:MySQL 5.x低版本兼容方案

借助自定义数字序列实现拆分去重:

SELECT COUNT(DISTINCT TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(b.room_id, ',', nums.n), ',', -1))) AS total
FROM booking b
JOIN (
    -- 数字序列的最大值需要大于单条room_id最多的元素个数,可按需扩展
    SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
) nums ON nums.n <= LENGTH(b.room_id) - LENGTH(REPLACE(b.room_id, ',', '')) + 1;

优化建议

逗号分隔存储关联ID的设计不符合数据库第一范式,后续数据量上升后查询、统计、关联操作的性能都会大幅下降,建议拆分为独立的booking_room关联表存储预订对应的房间ID,能大幅简化同类统计逻辑。

内容的提问来源于stack exchange,提问作者Samir Jana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 19:09:02