在PostgreSQL中的“ORDER BY … USING”子句

在PostgreSQL中的“ORDER BY … USING”子句,第1张

概述ORDER BY子句在PostgreSQL文档中描述为: ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] 有人可以给我一些例子如何使用USING运算符?是否可以获得结果集的交替顺序? 一个非常简单的例子是: > SELECT * FROM tab ORDER BY col ORDER BY子句在Postgresql文档中描述为:
ORDER BY Expression [ ASC | DESC | USING operator ] [ NulLS { FirsT | LAST } ] [,...]

有人可以给我一些例子如何使用USING运算符?是否可以获得结果集的交替顺序?

一个非常简单的例子是:
> SELECT * FROM tab ORDER BY col USING <

但这是无聊,因为这是没有什么你不能得到与传统的ORDER BY col ASC。

此外,标准目录没有提到任何令人兴奋的奇怪的比较函数/运算符。你可以得到他们的列表:

> SELECT amoplefttype::regtype,amoprighttype::regtype,amopopr::regoper       FROM pg_am JOIN pg_amop ON pg_am.oID = pg_amop.amopmethod       WHERE amname = 'btree' AND amopstrategy IN (1,5);

你会注意到,和>原始类型的函数,如整数,日期等,一些更多的数组和向量等。这些运算符都不会帮助您获得自定义排序。

在大多数情况下,需要定制排序,你可以使用类似的东西… ORDER BY somefunc(tablecolumn)… wherefunc适当地映射值。因为它适用于每个数据库,这也是最常见的方式。对于简单的事情,你甚至可以写一个表达式而不是自定义函数。

开关齿轮

ORDER BY … USING在以下情况下有意义:

>排序是如此罕见,somefunc技巧不工作。
>您使用非原始类型(如点,圆或虚数),并且不想在查询中使用奇怪的计算重复自己。
>您要排序的数据集太大,需要或甚至需要索引支持。

我将专注于复杂的数据类型:通常有多种方式以合理的方式对它们进行排序。一个很好的例子是point:你可以通过到(0,0)的距离,或者x先,然后y或者y或你想要的任何其他东西来“排序”他们。

当然,Postgresql有预定义的运算符:

> CREATE table p ( p point );    > SELECT p <-> point(0,0) FROM p;

但是没有一个被声明为可用于ORDER BY默认情况下(见上文):

> SELECT * FROM p ORDER BY p;    ERROR:  Could not IDentify an ordering operator for type point    TIP:  Use an explicit ordering operator or modify the query.

点的简单运算符是“下面”和“上面”运算符< ^和> ^。他们只是简单地比较点的y部分。但:

>  SELECT * FROM p ORDER BY p USING >^;    ERROR: operator > is not a valID ordering operator    TIP: Ordering operators must be "<" or ">" members of __btree__ operator familIEs.

ORDER BY USING需要一个具有定义语义的运算符:显然它必须是一个二进制运算符,它必须接受与参数相同的类型,并且必须返回boolean。我认为它也必须是可传递的(如果a< b和b< c,那么a< c)。可能有更多的要求。但是所有这些要求对于正确的btree-index排序也是必要的。这解释了包含对btree的引用的奇怪的错误消息。 ORDER BY USING还不仅需要定义一个运算符,还需要运算符类和运算符族。虽然可以实现只有一个 *** 作符排序,Postgresql尝试有效排序和最小化比较。因此,即使你只指定一个 *** 作符,其他 *** 作符也必须遵守某些数学约束 – 我已经提到了传输性,但还有更多。 开关Gears 让我们定义一些合适的:一个运算符,它只比较y部分。 第一步是创建一个可以由btree索引访问方法使用的自定义 *** 作符系列。 see

> CREATE OPERATOR FAMILY xyzfam USING btree;   -- superuser access required!    CREATE OPERATOR FAMILY

接下来,我们必须提供一个比较器函数,当比较两个点时返回-1,1。此函数将在内部调用!

> CREATE FUNCTION xyz_v_cmp(p1 point,p2 point) RETURNS int       AS $$BEGIN RETURN btfloat8cmp(p1[1],p2[1]); END $$ LANGUAGE plpgsql;    CREATE FUNCTION

接下来,我们为该系列定义运算符类。 See the manual的数字说明。

> CREATE OPERATOR CLASS xyz_ops FOR TYPE point USING btree FAMILY xyzfam AS         OPERATOR 1 <^,OPERATOR 3 ?-,OPERATOR 5 >^,FUNCTION 1 xyz_v_cmp(point,point) ;    CREATE OPERATOR CLASS

此步骤组合了多个运算符和函数,并定义了它们的关系和含义。例如OPERATOR 1表示:这是小于测试的运算符。

现在运算符< ^和'> ^’可以用于ORDER BY USING:

> INSERT INTO p SELECT point(floor(random()*100),floor(random()*100)) FROM generate_serIEs(1,5);INSERT 0 5> SELECT * FROM p ORDER BY p USING >^;    p    --------- (17,8) (74,57) (59,65) (0,87) (58,91)

Voila – 按y排序。

总结:ORDER BY … USING是一个有趣的外观下的Postgresql。但是没有什么你会需要很快,除非你在非常具体的数据库技术领域工作。

另一个示例可以找到in the Postgres docs.,其源代码为示例here和here.此示例还显示了如何创建运算符。

总结

以上是内存溢出为你收集整理的在PostgreSQL中的“ORDER BY … USING”子句全部内容,希望文章能够帮你解决在PostgreSQL中的“ORDER BY … USING”子句所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1171912.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存