Pervasive SQL中如何按BIN字段子串实现特定分组排序?
特殊分组排序的报表实现方案
需求说明
需要对零件存储位(BIN字段,格式如GS7A01,其中7为货架位置,A-E为楼层,01为货架编号)进行特殊排序:
- 先按货架位置(如
GS7A01中的7)归类 - 再按货架编号(末尾两位数字,如
01、02)排序,即先展示所有以01结尾的BIN记录,再依次展示02、03等 - 同货架编号下按楼层(
A到E)排序,最后按零件号(PART)排序
现有问题
当前查询的排序逻辑不符合需求,尝试按BIN子串分组时报错(要求必须按BIN字段分组,但添加BIN后无法按子串实现预期排序)。使用数据库为Pervasive SQL(与MySQL语法相近但有差异)。
现有查询语句
SELECT vim.BIN, vim.PART, vinvm.DESCRIPTION FROM V_ITEM_MASTER vim LEFT OUTER JOIN V_INVENTORY_MSTR vinvm ON (vim.PART = vinvm.PART) AND (vim.LOCATION = vinvm.LOCATION) WHERE vim.LOCATION = 'HN' and vim.BIN like 'GS%' ORDER BY substring(vim.bin,1,4),substring(vim.bin,5,2), vim.PART
当前结果
| BIN | Part | Description |
|---|---|---|
| GS7A01 | 874129 | EMERGENCY STOP, GENERATOR, PIL |
| GS7A01 | 880.20000.0150 | CONDUIT,2" AL LB, LB200A |
| GS7A02 | 880.99032.0001 | COLD SHRINK,1/0-4/0, 15KV |
| GS7A03 | 843044 | 1/4" OD 3/16" ID NYLON BLK TUB |
| GS7A03 | 8520134 | HHCS, SS, 1-1/8"-7 X 3.5"LG |
| GS7A03 | 8521166 | ACME THREADED ROD, 1"-4, 3FT |
| GS7A03 | 8571303 | TUBE, SS,1/4" OD X .035"WAL,6' |
| GS7A03 | 8571362 | BUSHING, DOUBLE TAP, 2"M X 1/2 |
| GS7A03 | 8571906 | BUSHING REDUCING,4"-2", 304SS |
| GS7A03 | 880.15029.0048 | LEVEL SENSOR, FLOAT, 4-20mA |
| GS7A04 | 880.99029.0067 | TERMINAL PAD KIT,3200A,3P |
| GS7A05 | 880.24021.0000 | CABLE GLAND,NYLON,1-1/2" |
| GS7A06 | 880.20094.0010 | CONN,METAL FLEX,3",STR,T&B |
| GS7A06 | 880.25069.0002 | LIGHT,EXTERIOR,AMZ,HOUSE GEN |
| GS7B02 | 8521012 | HHCS, SS, 5/8"-11 X 3.5" LG |
| GS7B02 | 8521014 | HHCS, SS, 5/8"-11 X 3" LG |
| GS7B02 | 8521052 | WASHER, BEVEL, 3/8, GALV. IRON |
| GS7B02 | 8521242 | HHCS, SS, Moly, 1"-8x2"LG |
| GS7B02 | 8521245 | WASHER, SQ, UNI-STRUT, 3/8",ZC |
| GS7B02 | 852951 | WASHER, BEVEL, GALV. IRON, 5/8 |
| GS7B02 | 880.99032.0002 | COLD SHRINK,#2-3/0, 15KV |
| GS7B03 | 8521163 | ACME HEX NUT, 1"-4, LH, 2G |
期望结果
| BIN | Part | Description |
|---|---|---|
| GS7A01 | 874129 | EMERGENCY STOP, GENERATOR, PIL |
| GS7A01 | 880.20000.0150 | CONDUIT,2" AL LB, LB200A |
| GS7B01 | xxxxxx | xxxxx |
| GS7C01 | yyyyyy | yyyyy |
| GS7A02 | 880.99032.0001 | blah blah blah |
| GS7B02 | 8521012 | HHCS, SS, 5/8"-11 X 3.5" LG |
| GS7B02 | 8521014 | HHCS, SS, 5/8"-11 X 3" LG |
| GS7B02 | 8521052 | WASHER, BEVEL, 3/8, GALV. IRON |
| GS7B02 | 8521242 | HHCS, SS, Moly, 1"-8x2"LG |
| GS7B02 | 8521245 | WASHER, SQ, UNI-STRUT, 3/8",ZC |
| GS7B02 | 852951 | WASHER, BEVEL, GALV. IRON, 5/8 |
| GS7B02 | 880.99032.0002 | COLD SHRINK,#2-3/0, 15KV |
解决方案
1. 通过Pervasive SQL直接实现
不需要使用GROUP BY,只需调整ORDER BY的排序逻辑即可满足需求。核心是按货架位置 → 货架编号 → 楼层 → 零件号的顺序排序:
SELECT vim.BIN, vim.PART, vinvm.DESCRIPTION FROM V_ITEM_MASTER vim LEFT OUTER JOIN V_INVENTORY_MSTR vinvm ON (vim.PART = vinvm.PART) AND (vim.LOCATION = vinvm.LOCATION) WHERE vim.LOCATION = 'HN' and vim.BIN like 'GS%' -- 排序逻辑:货架位置(第3位字符)→ 货架编号(末尾两位)→ 楼层(第4位字符)→ 零件号 ORDER BY SUBSTRING(vim.BIN, 3, 1), SUBSTRING(vim.BIN, 5, 2), SUBSTRING(vim.BIN, 4, 1), vim.PART
逻辑说明
SUBSTRING(vim.BIN, 3, 1):提取货架位置(如GS7A01中的7),确保同一货架的记录放在一起SUBSTRING(vim.BIN, 5, 2):提取末尾两位货架编号(如01、02),实现先展示所有01结尾的记录,再依次展示02、03等SUBSTRING(vim.BIN, 4, 1):提取楼层(如A、B),确保同编号下按底层到顶层排序vim.PART:最后按零件号排序
Pervasive SQL支持SUBSTRING函数,语法与MySQL兼容,因此该语句可以直接运行。
2. 备选:.NET ERP系统自定义脚本
如果因数据库权限或函数限制导致SQL无法实现,可在.NET架构的ERP系统中通过以下步骤处理:
- 用原查询获取所有数据
- 在内存中对数据进行排序:
- 先按BIN的第3位字符归类
- 再按BIN的末尾两位字符串排序
- 最后按BIN的第4位字符和PART排序
- 将排序后的数据生成报表
来源说明
内容的提问来源于stack exchange,提问作者SkylarPurifoy
相关产品推荐
相关产品推荐

