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

如何拆分单字段多零件数据并计算各国零件占比?SQL查询遇阻求助

解决方法

问题分析

原SQL语句的核心问题:

  • Parts_Used字段存储多个逗号分隔的零件编号,LIKE 'CH%'仅能匹配字段开头是CH的记录,无法识别字段中间或末尾的CH零件(比如IN_001,CH_002这类记录会被完全漏掉)。
  • 原语句仅统计符合条件的机器总数,没有实现「每台机器内CH/IN零件占比」的计算需求。

分步解决方案

1. 拆分多零件字段

首先需要把Parts_Used中的多个零件编号拆分为单独的行,不同SQL方言的实现方式如下:

MySQL/MariaDB(8.0+版本)

用递归CTE生成序列配合字符串拆分:

WITH RECURSIVE nums AS (
    SELECT 1 AS n
    UNION ALL
    SELECT n + 1 FROM nums WHERE n <= 100 -- 覆盖单条记录最多零件数,可按需调整
)
SELECT 
    machine_id,
    TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(Parts_Used, ',', n), ',', -1)) AS part
FROM tablename
CROSS JOIN nums
WHERE n <= 1 + LENGTH(Parts_Used) - LENGTH(REPLACE(Parts_Used, ',', ''));

PostgreSQL

利用string_to_array和unnest函数:

SELECT 
    machine_id,
    unnest(string_to_array(Parts_Used, ',')) AS part
FROM tablename;

SQL Server

使用内置STRING_SPLIT函数:

SELECT 
    machine_id,
    value AS part
FROM tablename
CROSS APPLY STRING_SPLIT(Parts_Used, ',');

2. 计算单台机器的零件占比

基于拆分后的零件数据,统计每台机器的CH/IN零件数量及占比:

WITH split_parts AS (
    -- 替换为对应SQL方言的拆分语句
    SELECT 
        machine_id,
        unnest(string_to_array(Parts_Used, ',')) AS part
    FROM tablename
)
SELECT 
    machine_id,
    COUNT(*) AS total_parts,
    SUM(CASE WHEN part LIKE 'CH%' THEN 1 ELSE 0 END) AS ch_parts,
    ROUND(SUM(CASE WHEN part LIKE 'CH%' THEN 1 ELSE 0 END)::FLOAT / COUNT(*) * 100, 2) AS ch_part_percentage,
    SUM(CASE WHEN part LIKE 'IN%' THEN 1 ELSE 0 END) AS in_parts,
    ROUND(SUM(CASE WHEN part LIKE 'IN%' THEN 1 ELSE 0 END)::FLOAT / COUNT(*) * 100, 2) AS in_part_percentage
FROM split_parts
GROUP BY machine_id;

3. 统计全量机器的整体零件占比

如果需要所有机器的CH/IN零件总占比,直接基于拆分后的汇总:

WITH split_parts AS (
    -- 替换为对应拆分语句
    SELECT 
        unnest(string_to_array(Parts_Used, ',')) AS part
    FROM tablename
)
SELECT 
    COUNT(*) AS total_parts,
    SUM(CASE WHEN part LIKE 'CH%' THEN 1 ELSE 0 END) AS ch_parts,
    ROUND(SUM(CASE WHEN part LIKE 'CH%' THEN 1 ELSE 0 END)::FLOAT / COUNT(*) * 100, 2) AS ch_part_percentage,
    SUM(CASE WHEN part LIKE 'IN%' THEN 1 ELSE 0 END) AS in_parts,
    ROUND(SUM(CASE WHEN part LIKE 'IN%' THEN 1 ELSE 0 END)::FLOAT / COUNT(*) * 100, 2) AS in_part_percentage
FROM split_parts;

额外建议

如果业务允许,建议重构数据表结构:将零件信息拆分为单独的关联表(比如machine_parts表,包含machine_id和part_id字段),彻底避免字段存储多值的设计,后续统计和维护会更高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 04:10:36