您是否能够为ORDER BY子句使用自定义Postgres比较函数?

Sea*_*ods 18 sorting postgresql

在Python中,我可以编写一个排序比较函数,它返回集合中的项目{-1, 0, 1}并将其传递给排序函数,如下所示:

sorted(["some","data","with","a","nonconventional","sort"], custom_function)
Run Code Online (Sandbox Code Playgroud)

此代码将根据我在函数中定义的归类顺序对序列进行排序.

我可以在Postgres中做相同的操作吗?

例如

SELECT widget FROM items ORDER BY custom_function(widget)
Run Code Online (Sandbox Code Playgroud)

编辑:欢迎使用示例和/或指向文档的指针.

Fra*_*ens 13

是的,你甚至可以创建一个功能索引来加速排序.

编辑:简单示例:

CREATE TABLE foo(
    id serial primary key,
    bar int
);
-- create some data
INSERT INTO foo(bar) SELECT i FROM generate_series(50,70) i;
-- show the result
SELECT * FROM foo;

CREATE OR REPLACE FUNCTION my_sort(int) RETURNS int 
LANGUAGE sql 
AS
$$
    SELECT $1 % 5; -- get the modulo (remainder)
$$;
-- lets sort!
SELECT *, my_sort(bar) FROM foo ORDER BY my_sort(bar) ASC;

-- make an index as well:
CREATE INDEX idx_my_sort ON foo ((my_sort(bar)));
Run Code Online (Sandbox Code Playgroud)

本手册充满了如何使用自己的功能的例子,只是开始玩它.

  • 弗兰克海肯斯,在我看来,你错过了这一点.Sean Woods说,Python中的函数包含两个元素并对它们进行比较.在PostgreSQL中,它会转换为接收两行并进行比较,然后返回更大的行.你是正确的,你可以创建一个用于排序的函数,它接受两个参数,但在我看来,这两个参数将来自SAME行,而不是两个不同的行. (3认同)

Pet*_*uss 5

我们可以避免使用名称来排序方法的混乱:

\n
    \n
  • 标准 SQL 子句的“评分函数”select * from t order by f(x),以及
  • \n
  • Python排序数组方法的“比较函数” (问题文本中的“排序函数”)。
  • \n
\n
\n

ORDER BYPostgreSQL的子句有3种排序机制:

\n
    \n
  1. 标准,使用“评分函数”,您也可以将其与 INDEX 一起使用。
  2. \n
  3. 特殊的“标准字符串比较替代方案”,通过排序规则配置
    (仅适用于textvarchar等数据类型)。
  4. \n
  5. ORDER BY ... USING条款。请参阅此问题文档示例
    示例:SELECT * FROM mytable ORDER BY somecol USING ~<~其中~<~是一个运算符,即嵌入一个比较函数
  6. \n
\n

也许RDBMS (如 PostgreSQL)中的“标准方式”与Python 的标准不同,因为索引是 RDBMS 的目标,并且索引评分函数更容易。

\n

问题的答案:

\n
    \n
  • 直接解决。没有直接的方法可以使用用户定义的函数作为比较函数,就像Python 或 Javascript 等语言的排序方法一样。

    \n
  • \n
  • 间接解决。您可以在用户定义的运算符中使用用户定义的比较函数,并使用 用户定义的运算符类对其进行索引。请参阅 PostgreSQL 文档:

    \n\n
  • \n
\n
\n

解释比较函数

\n

在 Python 中,比较函数如下所示:

\n
def compare(a, b):\n    return 1 if a > b else 0 if a == b else -1\n
Run Code Online (Sandbox Code Playgroud)\n

比较函数比评分函数使用更少的 CPU分数函数未知
时,表达顺序也很有用。

\n

请参阅以下位置的完整说明:

\n\n

其他典型比较功能

\n

维基百科比较元组的示例:

\n
function tupleCompare((lefta, leftb, leftc), (righta, rightb, rightc))\n    if lefta \xe2\x89\xa0 righta\n        return compare(lefta, righta)\n    else if leftb \xe2\x89\xa0 rightb\n        return compare(leftb, rightb)\n    else\n        return compare(leftc, rightc)\n
Run Code Online (Sandbox Code Playgroud)\n

在 JavaScript 中:

\n
function tupleCompare((lefta, leftb, leftc), (righta, rightb, rightc))\n    if lefta \xe2\x89\xa0 righta\n        return compare(lefta, righta)\n    else if leftb \xe2\x89\xa0 rightb\n        return compare(leftb, rightb)\n    else\n        return compare(leftc, rightc)\n
Run Code Online (Sandbox Code Playgroud)\n

PostgreSQL 文档的 C++ 示例:

\n
function compare(a, b) {\n  if (a is less than b by some ordering criterion) {\n    return -1;\n  }\n  if (a is greater than b by the ordering criterion) {\n    return 1;\n  }\n  // a must be equal to b\n  return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n