如果我执行这个简单的查询
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?
1条答案
按热度按时间wlzqhblo1#
使用
->>
运算符直接将排序值提取为text
。将
JSON
值强制转换为text
会执行一些不同的操作。您的尝试:
等效于以下设置:
我不知道 * 为什么 * 双引号会改变排序顺序。可能是因为它与底层的排序规则有关。也许可以创建一个ICU排序规则,将带引号的字符串与不带引号的字符串以同样的方式排序。