我正在尝试编写一个查询,该查询将返回按字母数字列Code排序的数据。
以下是我的询问:
SELECT *
FROM <<TableName>>
CROSS APPLY (SELECT PATINDEX('[A-Z, a-z][0-9]%', [Code]),
CHARINDEX('', [Code]) ) ca(PatPos, SpacePos)
CROSS APPLY (SELECT CONVERT(INTEGER, CASE WHEN ca.PatPos = 1 THEN
SUBSTRING([Code], 2,ISNULL(NULLIF(ca.SpacePos,0)-2, 8000)) ELSE NULL END),
CASE WHEN ca.PatPos = 1 THEN LEFT([Code],
ISNULL(NULLIF(ca.SpacePos,0)-0,1)) ELSE [Code] END) ca2(OrderBy2, OrderBy1)
WHERE [TypeID] = '1'
输出:
FFS1
FFS2
...
FFS12
FFS1.1
FFS1.2
...
FFS1.1E
FFS1.1R
...
FFS12.1
FFS12.2
FFS.12.1E
FFS12.1R
FFS12.2E
FFS12.2R
期望的输出:
FFS1
FFS1.1
FFS1.1E
FFS1.1R
....
FFS12
FFS12.1
FFS12.1E
FFS12.1R
我错过或忽略了什么?
编辑:
让我尝试更好地详细说明表格内容。有FFS1 - FFS12的记录。它们分为X个子,即FFS1.1 - FFS1.X到FFS12.1 - FFS12.X。 E和R不是拼写错误,每个子记录都有两个与之相关的代码:FFS1.1E&amp; FFS1.1R。
此外,我尝试使用ORDER BY,但它排序为
FFS1 ... FFS10 FFS2
答案 0 :(得分:0)
这适用于由点分隔的任何部件数。每个部分的分类是字母数字。
WITH Splittable AS
(
SELECT ID
,SomeVal
,CAST(N'<x>' + REPLACE(SomeVal,'.','</x><x>') + N'</x>' AS XML) AS Casted
FROM @YourValues
)
,Parted AS
(
SELECT Splittable.*
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS PartNmbr
,A.part.value(N'text()[1]','nvarchar(max)') AS Part
FROM Splittable
CROSS APPLY Splittable.Casted.nodes(N'/x') AS A(part)
)
,AddSortCrit AS
(
SELECT ID
,SomeVal
,(SELECT LEFT(x.Part + REPLICATE(' ',10),10) AS [*]
FROM Parted AS x
WHERE x.ID=Parted.ID
ORDER BY PartNmbr
FOR XML PATH('')
) AS SortColumn
FROM Parted
GROUP BY ID,SomeVal
)
SELECT ID
,SomeVal
FROM AddSortCrit
ORDER BY SortColumn;
- 查询
ID SomeVal
10 FFS.12.1E
1 FFS1
4 FFS1.1
6 FFS1.1E
7 FFS1.1R
5 FFS1.2
3 FFS12
8 FFS12.1
11 FFS12.1R
9 FFS12.2
12 FFS12.2E
13 FFS12.2R
2 FFS2
结果
SELECT
第一个CTE会将您的代码转换为XML,允许分别处理每个部分
第二个CTE返回每个部分以及一个数字
第三个CTE重新连接您的代码,但每个部分填充为10个字符的长度
最终的ORDER BY
在import re
fileNames = ['123456_BI12554_AA_0021.jpg', '123456_BI125546_AA_0021.jpg']
for fileName in fileNames:
print(re.findall(r'(_BI\d{5,6}_)', fileName))
#_BI12554_
#_BI125546_
中使用了这个新的每行单字符串。
这个设计很糟糕!您不应将这些值存储在连接的字符串中...将它们存储在单独的列中,并将它们放在一起,仅用于输出/表示层。这样做可以避免这种相当丑陋的小提琴......