我正在尝试使用以下 PostgreSQL 查询对表门中的列标题进行排序:
SELECT title
FROM door
ORDER BY
CASE
WHEN title ~ '^\d+' THEN CAST(regexp_replace(title, '[^0-9]', '', 'g') AS INTEGER)
ELSE NULL
END ASC,
CASE
WHEN title ~ '^\d+' THEN regexp_replace(title, '\d+', '', 'g')
ELSE title
END ASC;
查询当前产生以下结果:
"DR-1"
"DR-01"
"DR-02"
"DR-03"
"DR-04"
"DR-100"
"DR-1001"
"DR-101"
"DR-102"
"DR-104"
"Entrance-1"
"Entrance-2"
"MY-Prefix-10-Entrance-1"
"MY-Prefix-11-Entrance-1"
"MY-Prefix-19-Entrance-1"
"MY-Prefix-1-Entrance-1"
"MY-Prefix-20-Entrance-1"
"MY-Prefix-2-Entrance-1"
"MY-Prefix-3-Entrance-1"
"MY-Prefix-8-Entrance-1"
"MY-Prefix-9-Entrance-1"
"MY-Prefix-9-Entrance-2"
"MY-Prefix-9-Entrance-3"
然而,我期待的结果是:
"DR-1"
"DR-01"
"DR-02"
"DR-03"
"DR-04"
"DR-100"
"DR-101"
"DR-102"
"DR-104"
"DR-1001"
"Entrance-1"
"Entrance-2"
"MY-Prefix-1-Entrance-1"
"MY-Prefix-2-Entrance-1"
"MY-Prefix-3-Entrance-1"
"MY-Prefix-8-Entrance-1"
"MY-Prefix-9-Entrance-1"
"MY-Prefix-9-Entrance-2"
"MY-Prefix-9-Entrance-3"
"MY-Prefix-10-Entrance-1"
"MY-Prefix-11-Entrance-1"
"MY-Prefix-19-Entrance-1"
"MY-Prefix-20-Entrance-1"
查询未正确对标题列包含混合前缀和数字段的行进行排序,特别是具有 MY-Prefix 模式的条目。我怀疑这是由于 ORDER BY 子句中的逻辑未正确处理多段字母数字字符串的排序所致。
我想要:
对从
title
中提取数字段并按数字排序的行进行排序。
正确处理字母数字前缀,以便像 MY-Prefix-1-Entrance-1
这样的条目出现在 MY-Prefix-10-Entrance-1
之前。
对于示例数据模式,您可以将要排序的列拆分为两列,其中第一列新列仅包含非数字字符,第二列仅包含数字字符,并按如下方式排序。
with door as (
select title from (
values ('DR-1'), ('DR-01'), ('DR-02'), ('DR-03'), ('DR-04'), ('DR-100'), ('DR-1001'), ('DR-101'), ('DR-102'), ('DR-104'), ('Entrance-1'), ('Entrance-2'), ('MY-Prefix-10-Entrance-1'), ('MY-Prefix-11-Entrance-1'), ('MY-Prefix-19-Entrance-1'), ('MY-Prefix-1-Entrance-1'), ('MY-Prefix-20-Entrance-1'), ('MY-Prefix-2-Entrance-1'), ('MY-Prefix-3-Entrance-1'), ('MY-Prefix-8-Entrance-1'), ('MY-Prefix-9-Entrance-1'), ('MY-Prefix-9-Entrance-2'), ('MY-Prefix-9-Entrance-3')
) as ta (title)
)
select title
-- , REGEXP_REPLACE(title, '[[:digit:]]+', '', 'g')::text as chars
-- , REGEXP_REPLACE(title, '[^[:digit:]]+', '', 'g')::integer as numbers
from door order by
REGEXP_REPLACE(title, '[[:digit:]]+', '', 'g')::text,
REGEXP_REPLACE(title, '[^[:digit:]]+', '', 'g')::integer