带有 Postgres 子字符串的 Ecto 查询片段

Ecto Query Fragment with Postgres substring

场景
我需要对数据库中的顺序进行排序,然后是数字。
所以顺序应该是 ["A","B","C","1","2","3"]

Postgres
这似乎有效。我试过了。

WITH x(t) AS (
    VALUES
     ('a')
    ,('3')
    ,('2')
    ,('1')
    ,('c')
    ,('b')
    )
SELECT t
FROM   x
ORDER  BY (
substring(t, '^[A-Za-z].*'),       -- cast to integer 
substring(t, '[^0-9_].*$'))        -- works as text

我正在使用 Ecto,据我了解,您需要使用 Ecto.Query.API.fragment/1 才能向数据库发送命令。所以我写了这个。

In Ecto

def alphabetical(query) do
 from c in query, order_by: [fragment("substring(?, ?)", c.name, '^[A-Za-z].*'), fragment("substring(?, ?)", c.name, '[^0-9_].*$')]
end

错误
我在应用程序中收到此错误

ERROR 42883 (undefined_function): function pg_catalog.substring(character varying, integer[]) does not exist

回答
用 Ecto 编写并使用片段

  def alphabetical(query) do
      from c in query, order_by: [fragment("? < 'a'", c.name)]
  end

您的查询似乎不正确。试试这个简单的:

SELECT t
FROM x
ORDER BY t < 'a', t

Db<>fiddle.