TSQL 获取范围或逗号分隔的数字
TSQL Get Numbers as Range or Comma delimited
我正在尝试组合包装数量,按订单号分组。
目前我将它与 STUFF 结合起来作为逗号分隔的字符串。
所以我现在举个例子:1-001、1-002、1-003
但是如果数字是 1-001、1-002、1-003、1-004、1-007,我想得到这个 Packagenumbers 的范围是有序的,这个范围(或单个包装)逗号分隔。
示例:
Packagings: 1-001, 1-002, 1-003, 1-004, 1-007, 1-008, 2-001
Expected: 1-001 to 1-004, 1-007 to 1-008, 2-001
我目前的方法是这样的:
SELECT
o.OrderNumber
, op.PositionNumber
, STUFF((
SELECT ',' + ifp.Packnumber
FROM FilledPackage ifp
INNER JOIN PositionInFIlledPackage pifp
ON ifp.FilledPackageId = pifp.FilledPackageId
WHERE
ifp.OrderNumber = o.OrderNumber
AND pifp.PositionNumber = op.PositionNumber
ORDER BY ifp.Code, ifp.PackOfTypeCounter
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
,1,1,'') AS Packagings
FROM MyOrder o
INNER JOIN MyPosition op
ON o.OrderId = op.OrderId
GROUP BY
o.OrderNumber
, op.PositionNumber
- ifp.Code 是包装类型(如 1-00x 中的 1)
- ifp.PackOfTypeCounter 是一个类型的当前包号(比如 x-001 中的 1)
- PackNumber 是一个类似于 1-002 的字符串(1 => Package Type,2 => PackageNumber)
示例:PackNumber = ifp.Code + "-" + ifp.PackOfTypeCounter
有人知道这怎么可能吗?
最后我想要这样的东西:
Position 1: Pack: 4-001 to 4-008
Position 2: Pack: 1-001 to 1-004, 2-001 to 2-002, 4-009
Position 3: Pack: 4-010
Position 3: Pack: 1-005 to 1-007, 4-011
从这样的角度来看:
- 订单号
- 职位编号
- PackagingCode (int) => PackageType => 1
- PackOfTypeCounter (int) => 001
- 完整包裹编号 (1-001)
感谢您的帮助
你问的太多了,我们先关注这个需求:
Packagings: 1-001, 1-002, 1-003, 1-004, 1-007, 1-008, 2-001
Expected: 1-001 to 1-004, 1-007 to 1-008, 2-001
有了 DelimitedSplit8K 和一些解决间隙和孤岛的基本知识,这就有点容易了:
DECLARE @packagings VARCHAR(1000) = '1-001, 1-002, 1-003, 1-004, 1-007, 1-008, 2-001';
SELECT STUFF(
(
SELECT
', '+
CASE
WHEN MIN(g.txt) = MAX(g.txt)
THEN CAST(g.txtGroup AS VARCHAR(100))+'-'+CAST(MIN(g.txt) AS VARCHAR(100))
ELSE CAST(g.txtGroup AS VARCHAR(100))+'-'+CAST(MIN(g.txt) AS VARCHAR(100))+' to '+
CAST(g.txtGroup AS VARCHAR(100))+'-'+CAST(MAX(g.txt) AS VARCHAR(100))
END
FROM
(
SELECT txtGroup = t1.txt, t2.txt, grouper = t2.txt - split.ItemNumber
FROM dbo.DelimitedSplit8K(REPLACE(@packagings,' ',''),',') AS split
CROSS APPLY (VALUES(CHARINDEX('-', split.item))) AS mid(pos)
CROSS APPLY (VALUES(SUBSTRING(split.item,1,mid.pos-1))) AS t1(txt)
CROSS APPLY (VALUES(SUBSTRING(split.item,mid.pos+1,8000))) AS t2(txt)
) g
GROUP BY g.txtGroup, g.grouper
ORDER BY g.txtGroup
FOR XML PATH('')
),1,2,'');
Returns:
1-001 to 1-004, 1-007 to 1-008, 2-001
我正在尝试组合包装数量,按订单号分组。 目前我将它与 STUFF 结合起来作为逗号分隔的字符串。 所以我现在举个例子:1-001、1-002、1-003
但是如果数字是 1-001、1-002、1-003、1-004、1-007,我想得到这个 Packagenumbers 的范围是有序的,这个范围(或单个包装)逗号分隔。
示例:
Packagings: 1-001, 1-002, 1-003, 1-004, 1-007, 1-008, 2-001
Expected: 1-001 to 1-004, 1-007 to 1-008, 2-001
我目前的方法是这样的:
SELECT
o.OrderNumber
, op.PositionNumber
, STUFF((
SELECT ',' + ifp.Packnumber
FROM FilledPackage ifp
INNER JOIN PositionInFIlledPackage pifp
ON ifp.FilledPackageId = pifp.FilledPackageId
WHERE
ifp.OrderNumber = o.OrderNumber
AND pifp.PositionNumber = op.PositionNumber
ORDER BY ifp.Code, ifp.PackOfTypeCounter
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
,1,1,'') AS Packagings
FROM MyOrder o
INNER JOIN MyPosition op
ON o.OrderId = op.OrderId
GROUP BY
o.OrderNumber
, op.PositionNumber
- ifp.Code 是包装类型(如 1-00x 中的 1)
- ifp.PackOfTypeCounter 是一个类型的当前包号(比如 x-001 中的 1)
- PackNumber 是一个类似于 1-002 的字符串(1 => Package Type,2 => PackageNumber) 示例:PackNumber = ifp.Code + "-" + ifp.PackOfTypeCounter
有人知道这怎么可能吗?
最后我想要这样的东西:
Position 1: Pack: 4-001 to 4-008
Position 2: Pack: 1-001 to 1-004, 2-001 to 2-002, 4-009
Position 3: Pack: 4-010
Position 3: Pack: 1-005 to 1-007, 4-011
从这样的角度来看:
- 订单号
- 职位编号
- PackagingCode (int) => PackageType => 1
- PackOfTypeCounter (int) => 001
- 完整包裹编号 (1-001)
感谢您的帮助
你问的太多了,我们先关注这个需求:
Packagings: 1-001, 1-002, 1-003, 1-004, 1-007, 1-008, 2-001
Expected: 1-001 to 1-004, 1-007 to 1-008, 2-001
有了 DelimitedSplit8K 和一些解决间隙和孤岛的基本知识,这就有点容易了:
DECLARE @packagings VARCHAR(1000) = '1-001, 1-002, 1-003, 1-004, 1-007, 1-008, 2-001';
SELECT STUFF(
(
SELECT
', '+
CASE
WHEN MIN(g.txt) = MAX(g.txt)
THEN CAST(g.txtGroup AS VARCHAR(100))+'-'+CAST(MIN(g.txt) AS VARCHAR(100))
ELSE CAST(g.txtGroup AS VARCHAR(100))+'-'+CAST(MIN(g.txt) AS VARCHAR(100))+' to '+
CAST(g.txtGroup AS VARCHAR(100))+'-'+CAST(MAX(g.txt) AS VARCHAR(100))
END
FROM
(
SELECT txtGroup = t1.txt, t2.txt, grouper = t2.txt - split.ItemNumber
FROM dbo.DelimitedSplit8K(REPLACE(@packagings,' ',''),',') AS split
CROSS APPLY (VALUES(CHARINDEX('-', split.item))) AS mid(pos)
CROSS APPLY (VALUES(SUBSTRING(split.item,1,mid.pos-1))) AS t1(txt)
CROSS APPLY (VALUES(SUBSTRING(split.item,mid.pos+1,8000))) AS t2(txt)
) g
GROUP BY g.txtGroup, g.grouper
ORDER BY g.txtGroup
FOR XML PATH('')
),1,2,'');
Returns:
1-001 to 1-004, 1-007 to 1-008, 2-001