postgresql 从列中提取子字符串的Order by case语句

yhived7q  于 2024-01-07  发布在  PostgreSQL
关注(0)|答案(2)|浏览(143)

我有下面的SQL,它只接受从Name列到出现空格或连字符的位置的数据。我想按case语句的输出对结果进行排序,但找不到方法。

select 

case 
when strpos("Name",' ') > 0 then substr("Name", 0, strpos("Name", ' '))
when strpos("Name",'-') > 0 then substr("Name", 0, strpos("Name", '-'))
else "Name"
end as StrippedName

from myTable

order by "StrippedName"

字符串

kq4fsx7k

kq4fsx7k1#

只要您对case的名称加上双引号,就完全可以得到 * select列表 * 和 * order by。不匹配的引号会使case生成一个名为strippedname的列,而order by查找StrippedName但没有找到,从而引发

ERROR:  column "StrippedName" does not exist
LINE 9: order by "StrippedName";
                 ^

字符串
如果你在两个地方都放上引号,或者在两个地方都使用引号,它会很好地工作:demo at db<>fiddle

create table myTable ("Name" text);
insert into myTable values ('2abc-def'),('3abcdef'),('1abc def')

select case 
         when strpos("Name",' ') > 0 
           then substr("Name", 0, strpos("Name", ' '))
         when strpos("Name",'-') > 0 
           then substr("Name", 0, strpos("Name", '-'))
         else "Name"
       end as "StrippedName" --without " it was folded to "strippedname"
from myTable
order by "StrippedName"--was looking for a case-sensitive "StrippedName"
--order by 1 --you could also pick a column by its position


| StrippedName|
| --|
| 1abc|
| 2abc|
| 3abcdef|
来自PostgreSQL词法结构文档的提示:
引用标识符也会使其区分大小写,而未引用的名称则始终折叠为小写。
您也可以使用列位置而不是其名称:order by 1
每个表达式可以是输出列(SELECT列表项)的名称或序号,也可以是由输入列值形成的任意表达式。
possible将整个case缩减为一个带有POSIX正则表达式的子字符串:

select regexp_substr("Name",'([^ -]+)') as "StrippedName"
from myTable 
order by "StrippedName"


它寻找的字符序列不是连字符-或空格``,所以它会返回任何一个字符的第一个位置之前的所有字符(如果两者都没有找到,则返回整个字符)。使用+而不是*可以跳过前导分隔符,寻找非空匹配。

pinkon5k

pinkon5k2#

你可以使用一个子查询:

select  *
from    (
        select  case ... end as col1
        from    ...
        ) as SubQueryAlias
order by
        col1

字符串

相关问题