Postgres文本排序:白色比json字符串中的字符串结尾小-错误还是按预期工作?

lp0sw83n  于 2023-02-14  发布在  其他
关注(0)|答案(1)|浏览(152)

如果我执行这个简单的查询

SELECT * 
FROM (
  SELECT 'abc' AS name 
  UNION ALL 
  SELECT 'abc d' AS name
) AS test 
ORDER BY name;

我得到了如下结果(正如预期的那样):

name
-------
 abc
 abc d
(2 rows)

即串abc d的空格字符被认为大于串abc的结尾。
到这里一切都很好。
接下来,如果我尝试:

SELECT * FROM (
  SELECT '{"name":"AbC"}'::JSON AS json
  UNION ALL
  SELECT '{"name":"aBc D"}'::JSON AS json
) AS test ORDER BY LOWER((json -> 'name')::TEXT);

我得到:

json
------------------
 {"name":"aBc D"}
 {"name":"AbC"}
(2 rows)

这次字符串abc d的空格字符被认为比abc的字符串**的末尾小!
我还尝试了:

SELECT * 
FROM (
  SELECT 'abc'::TEXT AS name 
  UNION ALL SELECT 'abc d'::TEXT AS name
) AS test 
ORDER BY name;
SELECT * 
FROM (
  SELECT 'abc' AS name 
  UNION ALL 
  SELECT 'abc d' AS name
) AS test 
ORDER BY LOWER(name);
SELECT * 
FROM (
  SELECT 'abc'::TEXT AS name 
  UNION ALL 
  SELECT 'abc d'::TEXT AS name
) AS test 
ORDER BY LOWER(name);

并且它们都给出了预期的结果。
我也试过:

SELECT * FROM (
  SELECT '{"name":"abc"}'::JSON AS json
  UNION ALL
  SELECT '{"name":"abc d"}'::JSON AS json
) AS test 
ORDER BY (json -> 'name')::TEXT;

其也考虑小于字符串结尾的空格字符。
看起来 * unexpected * 行为是由JSON字段的字符串属性转换为(任何?)postgres字符串类型引起的。我试图在PostrgeSQL文档中搜索此现象的原因,但我无法搜索到。
有人能告诉我关于这个的文档吗?或者我们应该认为这是一个bug?

wlzqhblo

wlzqhblo1#

使用->>运算符直接将排序值提取为text

SELECT * 
FROM (
  SELECT '{"name":"AbC"}'::JSON AS json
  UNION ALL
  SELECT '{"name":"aBc D"}'::JSON AS json
) AS test 
ORDER BY LOWER(json ->> 'name');

JSON值强制转换为text会执行一些不同的操作。
您的尝试:

SELECT * 
FROM (
  SELECT '{"name":"abc"}'::JSON AS json
  UNION ALL
  SELECT '{"name":"abc d"}'::JSON AS json
) AS test 
ORDER BY lower((json -> 'name')::TEXT);

等效于以下设置:

SELECT * 
FROM (
  SELECT '"abc"' AS name 
  UNION ALL 
  SELECT '"abc d"' AS name
) AS test 
ORDER BY name;

我不知道 * 为什么 * 双引号会改变排序顺序。可能是因为它与底层的排序规则有关。也许可以创建一个ICU排序规则,将带引号的字符串与不带引号的字符串以同样的方式排序。

相关问题