在Python中,我可以编写一个排序比较函数,它返回集合{-1, 0, 1}
中的一个项目并将其传递给类似的排序函数:
sorted(["some","data","with","a","nonconventional","sort"], custom_function)
此代码将根据我在函数中定义的归类顺序对序列进行排序。
我可以在Postgres中做相同的操作吗?
e.g。
SELECT widget FROM items ORDER BY custom_function(widget)
编辑:欢迎提供文档示例和/或指示。
答案 0 :(得分: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)));
本手册充满了如何使用自己的功能的例子,只是开始玩它。
答案 1 :(得分:0)
你可以做这样的事情
SELECT DISTINCT ON (interval_alias) *,
to_timestamp(floor((extract('epoch' FROM index.created_at) / 10)) * 10) AT
TIME ZONE 'UTC' AS interval_alias
FROM index
WHERE index.created_at >= '{start_date}'
AND index.created_at <= '{end_date}'
AND product = '{product_id}'
GROUP BY id, interval_alias
ORDER BY interval_alias;
首先,您使用AS
定义将作为订购列的参数。它可以是 function 或任何 SQL表达式。然后将其设置为ORDER BY
表达式,您就完成了!
在我看来,这是进行这种排序的最顺畅的方式。
答案 2 :(得分:0)
我们可以避免对使用名称的ordering methods感到困惑:
select * from t order by f(x)
子句的 PostgreSQL的ORDER BY
子句具有 3种机制进行排序:
text
,varchar
等数据类型)。 ORDER BY ... USING
子句。请参阅this question或docs example。 SELECT * FROM mytable ORDER BY somecol USING ~<~
,其中~<~
是运算符,它嵌入了比较函数。也许RDBMS(作为PostgreSQL)中的“标准方式”与Python的标准不同,因为索引是RDBMS的目标,并且更容易对评分函数进行索引。
问题的答案:
直接解决方案。 没有直接的方法将用户定义的函数用作比较函数,就像在Python或Javascript之类的 sort方法中一样。< / p>
间接解决方案。您可以在用户定义的运算符中使用用户定义的比较函数,并使用用户定义的运算符类对其进行索引。请参见PostgreSQL文档:
CREATE OPERATOR和 compare函数;
CREATE OPERATOR CLASS,以便可索引。
在Python中,比较功能如下所示:
def compare(a, b):
return 1 if a > b else 0 if a == b else -1
比较功能比得分功能 使用的CPU少。
在得分函数未知的情况下表达命令也是有用的。
请参阅完整的说明
Wikipedia's example比较元组:
function tupleCompare((lefta, leftb, leftc), (righta, rightb, rightc))
if lefta ≠ righta
return compare(lefta, righta)
else if leftb ≠ rightb
return compare(leftb, rightb)
else
return compare(leftc, rightc)
在Java语言中:
function compare(a, b) {
if (a is less than b by some ordering criterion) {
return -1;
}
if (a is greater than b by the ordering criterion) {
return 1;
}
// a must be equal to b
return 0;
}
PostgreSQL docs的C ++示例:
complex_abs_cmp_internal(Complex *a, Complex *b)
{
double amag = Mag(a),
bmag = Mag(b);
if (amag < bmag)
return -1;
if (amag > bmag)
return 1;
return 0;
}