【问题标题】:How to return records in correct order in PostgreSQL如何在 PostgreSQL 中以正确的顺序返回记录
【发布时间】:2012-12-03 10:20:55
【问题描述】:

查询

select 'T' union all select 'Z'  order by 1

返回

Z
T

但正确的顺序应该是

T
Z

在 3 种不同的操作系统中尝试过

  • Windows 2003 服务器“PostgreSQL 9.1.3,由 Visual C++ build 1500 编译,32 位”
  • Windows 7 "PostgreSQL 9.2.1,由 Visual C++ build 1600 编译,32 位"
  • Debian“x86_64-unknown-linux-gnu 上的 PostgreSQL 9.1.2,由 gcc-4.4.real (Debian 4.4.5-8) 4.4.5, 64-bit 编译”

数据库设置为:

Collation:      et_EE.UTF-8 
Character type: et_EE.UTF-8

如何解决这个问题?

更新

数据库是使用

创建的
CREATE DATABASE mydb WITH TEMPLATE=template0 OWNER=mydb_owner ENCODING='UNICODE'

操作系统语言环境在所有情况下都是爱沙尼亚语,因此数据库是在爱沙尼亚语语言环境中创建的。

select 'Z' collate "et_EE" union all select 'S' collate "et_EE" order by 1

返回正确的顺序:

S
Z

但是

select 'Z' collate "et_EE" union all select 'T' collate "et_EE" order by 1

如回答中所述返回无效订单:

Z
T

【问题讨论】:

  • 除了此顺序根据爱沙尼亚排序规则有效 - Z 必须在 T 之前
  • 还有:PostgreSQL 9.1.3?我引用项目页面:We always recommend that all users run the latest available minor release for whatever major version is in use. 那将是 9.1.7。

标签: sql postgresql sql-order-by locale collation


【解决方案1】:

原始 SQL 没有任何问题。

因为您使用爱沙尼亚语言环境,但 Estonian collation rules 要求“Z”在“T”之前,它似乎没有按您期望的方式工作的原因。

您可以使用不同的排序规则或在 en_US.UTF-8 语言环境中创建数据库。

【讨论】:

  • 谢谢。试过但它仍然返回无效的订单:Z,T
  • 它适用于 en_US.UTF-8。不幸的是,SQLFiddle 不喜欢这样,所以我不能在 SQLFiddle 中显示它
  • 你能试试爱沙尼亚语言环境 (et_EE.UTF-8)。您可以在此语言环境中创建数据库。在实际表中,字母 Z 排在 T 之前,原因不明
  • select 'T' union all select 'A' order by 1 返回正确的结果。所以我认为 order by 会影响整个查询结果
  • order by 适用于联合的结果。 @Andrus 问题是另一个问题。他的例子对我有用。
【解决方案2】:

没有查询有问题。

UNION [ALL](或INTERSECTEXCEPT)查询被视为一个查询。 ORDER BY 适用于所有腿的联合,而不仅仅是最后一个。您必须使用括号将ORDER BY 设置为查询的一个分支。引用手册here

select_statement UNION [ ALL | DISTINCT ] select_statement

select_statement 是任何没有ORDER BYLIMITSELECT 语句, FOR UPDATEFOR SHARE 子句。 (ORDER BYLIMIT可以附加 如果子表达式被括在括号中。没有 括号中,这些条款将被视为适用于结果 UNION,而不是它的右手输入表达式。)

这很有效(ab 之前排序):

SELECT 'b'
UNION ALL
SELECT 'a'
ORDER BY 1

问题中的原始查询也是如此:

SELECT 'T' 
UNION ALL
SELECT 'Z'
ORDER BY 1

检查您的排序规则:

SHOW lc_collate;

et_EE.UTF-8 是爱沙尼亚语语言环境,ZEstonian alphabet 中位于 T 之前。就是这样。

没有排序有问题。

【讨论】:

    【解决方案3】:

    问题在于排序规则:

    select 'T' collate "et_EE.utf8" a union all select 'Z' collate "et_EE.utf8" order by 1;
     a 
    ---
     Z
     T
    

    虽然使用 en_US 排序规则,但它可以工作:

    select 'T' collate "en_US.utf8" a union all select 'Z' collate "en_US.utf8" order by 1;
     a 
    ---
     T
     Z
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-29
      • 1970-01-01
      • 2019-10-06
      • 1970-01-01
      • 2022-11-16
      相关资源
      最近更新 更多