substring 、left、 PATINDEX

本文介绍了一种使用SQL的substring、left及PATINDEX函数从包含特定格式的数据中提取数字的方法。通过实例演示如何从带有连字符的字段中分离出前面的数字部分。

如图,表wenzhang中 qishiye 为空,想将yemafw 中,含有数字格式的数据,-前的数字 放到 qishiye 中。组合用 substring 、left、 PATINDEX 实现。


用 patindex 查找到 - 的起始位置  patindex('%-%',yemafw) 


select left(yemafw,patindex('%-%',yemafw)-1) from wenzhang where yemafw like '%-%'

select substring(yemafw,1,patindex('%-%',yemafw)-1)  from wenzhang where yemafw like '%-%'

WITH OPList AS ( SELECT Op, – 提取数字部分用于排序 CAST(SUBSTRING(op, 3, PATINDEX(‘%0-9%’, SUBSTRING(op, 3, LEN(op)) + ‘X’) - 1) AS INT) AS num_part, – 判断是否为纯数字 CASE WHEN SUBSTRING(op, 3 + PATINDEX(‘%0-9%’, SUBSTRING(op, 3, LEN(op)) + ‘X’) - 1, LEN(op)) = ‘’ THEN 1 ELSE 0 END AS is_pure_num, – 提取字母部分 SUBSTRING(op, 3 + PATINDEX(‘%0-9%’, SUBSTRING(op, 3, LEN(op)) + ‘X’) - 1, LEN(op)) AS letter_part FROM [dbo].[T_fault_tag_edit] WHERE op NOT LIKE ‘%900%’ AND part = ‘缸体’ GROUP BY op ), AllLines AS ( SELECT line1 AS OP FROM [dbo].[自主保全成果展示] WHERE 部门 = ‘第3制造科’ AND 线组 = ‘缸体组’ UNION ALL SELECT line2 AS OP FROM [dbo].[自主保全成果展示] WHERE 部门 = ‘第3制造科’ AND 线组 = ‘缸体组’ ) SELECT O.Op, COUNT(A.OP) AS WITH OPList AS ( SELECT Op, – 提取数字部分用于排序 CAST(SUBSTRING(op, 3, PATINDEX(‘%0-9%’, SUBSTRING(op, 3, LEN(op)) + ‘X’) - 1) AS INT) AS num_part, – 判断是否为纯数字 CASE WHEN SUBSTRING(op, 3 + PATINDEX(‘%0-9%’, SUBSTRING(op, 3, LEN(op)) + ‘X’) - 1, LEN(op)) = ‘’ THEN 1 ELSE 0 END AS is_pure_num, – 提取字母部分 SUBSTRING(op, 3 + PATINDEX(‘%0-9%’, SUBSTRING(op, 3, LEN(op)) + ‘X’) - 1, LEN(op)) AS letter_part FROM [dbo].[T_fault_tag_edit] WHERE op NOT LIKE ‘%900%’ AND part = ‘缸体’ GROUP BY op ), AllLines AS ( SELECT line1 AS OP FROM [dbo].[自主保全成果展示] WHERE 部门 = ‘第3制造科’ AND 线组 = ‘缸体组’ UNION ALL SELECT line2 AS OP FROM [dbo].[自主保全成果展示] WHERE 部门 = ‘第3制造科’ AND 线组 = ‘缸体组’ ) SELECT O.Op, COUNT(A.OP) AS OccurrenceCount FROM OPList O LEFT JOIN AllLines A ON O.Op = A.OP GROUP BY O.Op, O.num_part, O.is_pure_num, O.letter_part ORDER BY O.num_part, O.is_pure_num, O.letter_part; WITH OPList AS ( SELECT Op, – 提取数字部分用于排序 CAST(SUBSTRING(op, 3, PATINDEX(‘%0-9%’, SUBSTRING(op, 3, LEN(op)) + ‘X’) - 1) AS INT) AS num_part, – 判断是否为纯数字 CASE WHEN SUBSTRING(op, 3 + PATINDEX(‘%0-9%’, SUBSTRING(op, 3, LEN(op)) + ‘X’) - 1, LEN(op)) = ‘’ THEN 1 ELSE 0 END AS is_pure_num, – 提取字母部分 SUBSTRING(op, 3 + PATINDEX(‘%0-9%’, SUBSTRING(op, 3, LEN(op)) + ‘X’) - 1, LEN(op)) AS letter_part FROM [dbo].[T_fault_tag_edit] WHERE op NOT LIKE ‘%900%’ AND part = ‘缸体’ GROUP BY op ), AllLines AS ( SELECT line1 AS OP FROM [dbo].[自主保全成果展示] WHERE 部门 = ‘第3制造科’ AND 线组 = ‘缸体组’ UNION ALL SELECT line2 AS OP FROM [dbo].[自主保全成果展示] WHERE 部门 = ‘第3制造科’ AND 线组 = ‘缸体组’ ) SELECT O.Op, COUNT(A.OP) AS OccurrenceCount FROM OPList O LEFT JOIN AllLines A ON O.Op = A.OP GROUP BY O.Op, O.num_part, O.is_pure_num, O.letter_part ORDER BY O.num_part, O.is_pure_num, O.letter_part; WITH OPList AS ( SELECT Op, – 提取数字部分用于排序 CAST(SUBSTRING(op, 3, PATINDEX(‘%0-9%’, SUBSTRING(op, 3, LEN(op)) + ‘X’) - 1) AS INT) AS num_part, – 判断是否为纯数字 CASE WHEN SUBSTRING(op, 3 + PATINDEX(‘%0-9%’, SUBSTRING(op, 3, LEN(op)) + ‘X’) - 1, LEN(op)) = ‘’ THEN 1 ELSE 0 END AS is_pure_num, – 提取字母部分 SUBSTRING(op, 3 + PATINDEX(‘%0-9%’, SUBSTRING(op, 3, LEN(op)) + ‘X’) - 1, LEN(op)) AS letter_part FROM [dbo].[T_fault_tag_edit] WHERE op NOT LIKE ‘%900%’ AND part = ‘缸体’ GROUP BY op ), AllLines AS ( SELECT line1 AS OP FROM [dbo].[自主保全成果展示] WHERE 部门 = ‘第3制造科’ AND 线组 = ‘缸体组’ UNION ALL SELECT line2 AS OP FROM [dbo].[自主保全成果展示] WHERE 部门 = ‘第3制造科’ AND 线组 = ‘缸体组’ ) SELECT O.Op, COUNT(A.OP) AS OccurrenceCount FROM OPList O LEFT JOIN AllLines A ON O.Op = A.OP GROUP BY O.Op, O.num_part, O.is_pure_num, O.letter_part ORDER BY O.num_part, O.is_pure_num, O.letter_part; OccurrenceCount 统计数量时分为line1,line2 数量
11-11
WITH ProcessCount AS ( -- 步骤1: 计算每个线组/节拍的工序数量 SELECT 线组, 生产节拍, COUNT(DISTINCT 工序) AS 工序数量 FROM [dbo].[ods_TPS作业组合表] WHERE 要素时间 <> '0' AND LEFT(年月,7) = '${年月}' AND 产线 = '${产线}' AND 线组 = '${线组}' AND 生产节拍 = '${TT}' GROUP BY 线组, 生产节拍 ), BaseData AS ( -- 步骤2: 原始查询逻辑 SELECT id, 年月, t.线组, 工序, 作业要素, 要素时间, COALESCE(SUM(CAST(要素时间 AS INT)) OVER ( PARTITION BY t.线组, 工序, 生产节拍 ORDER BY 要素顺序 ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING ), 0) AS 累计要素时间, CASE WHEN 自动时间 > 0 THEN 100 ELSE NULL END AS 自动目标要素时间, CASE WHEN 作业类型 = '步行作业' OR 作业要素 LIKE '%步行%' THEN 100 ELSE NULL END AS 步行目标要素时间, 自动时间, 作业类型, CONVERT(INT, 生产节拍) AS 生产节拍, CASE WHEN ROW_NUMBER() OVER ( PARTITION BY t.线组, 工序, 生产节拍 ORDER BY 要素顺序 DESC ) = 1 THEN CONVERT(INT, 生产节拍) - COALESCE(SUM(CONVERT(INT, 要素时间)) OVER ( PARTITION BY t.线组, 工序, 生产节拍 ORDER BY 要素顺序 ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ), 0) - CONVERT(INT, 要素时间) ELSE NULL END AS 差距时间, CONVERT(INT, 要素顺序) AS 要素顺序, 改善类型, 产线, 机型分类, 机型, t.生产节拍 AS 生产节拍原始值 -- 保留原始值用于连接 FROM [dbo].[ods_TPS作业组合表] t WHERE 要素时间 <> '0' AND LEFT(年月,7) = '${年月}' AND 产线 = '${产线}' AND t.线组 = '${线组}' AND t.生产节拍 = '${TT}' ) -- 步骤3: 添加动态换行处理 SELECT id, 年月, 线组, 工序, -- 动态换行逻辑 CONCAT( CAST(要素顺序 AS VARCHAR), '-', CASE -- 根据工序数量设置不同换行规则 WHEN pc.工序数量 <= 16 AND LEN(作业要素) > 10 THEN SUBSTRING(作业要素, 1, 10) + CHAR(10) + SUBSTRING(作业要素, 11, LEN(作业要素)) WHEN pc.工序数量 > 16 AND pc.工序数量 <= 20 AND LEN(作业要素) > 6 THEN SUBSTRING(作业要素, 1, 6) + CHAR(10) + SUBSTRING(作业要素, 7, LEN(作业要素)) WHEN pc.工序数量 > 20 AND LEN(作业要素) > 5 THEN SUBSTRING(作业要素, 1, 5) + CHAR(10) + SUBSTRING(作业要素, 6, LEN(作业要素)) ELSE 作业要素 END ) AS 作业要素, 要素时间, 累计要素时间, 自动目标要素时间, 步行目标要素时间, 自动时间, 作业类型, 生产节拍, 差距时间, 要素顺序, 改善类型, 产线, 机型分类, 机型 FROM BaseData bd INNER JOIN ProcessCount pc ON bd.线组 = pc.线组 AND bd.生产节拍原始值 = pc.生产节拍 -- 使用原始值匹配 ORDER BY 要素顺序, CASE WHEN 工序 LIKE '[0-9][0-9]%' OR 工序 LIKE '[0-9][^0-9]%' OR 工序 LIKE '[0-9]' THEN CAST(LEFT(工序, PATINDEX('%[^0-9]%', 工序 + ' ') - 1) AS INT) END;
最新发布
11-14
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值