【问题标题】:CASE on ORDER BY based on field type基于字段类型的 ORDER BY 上的 CASE
【发布时间】:2022-07-18 21:10:37
【问题描述】:

考虑到字段值类型,如何执行ORDER BY

CREATE TABLE public.test(
    data jsonb
);

TRUNCATE test;

INSERT INTO test (data) VALUES ('{"age":2, "name": "b"}');
INSERT INTO test (data) VALUES ('{"age":1, "name": "cc"}');
INSERT INTO test (data) VALUES ('{"age":4, "name": "d"}');
INSERT INTO test (data) VALUES ('{"age":33, "name": "a"}');

-- works
SELECT * FROM test ORDER BY data->>'name' ASC; 
-- works
SELECT * FROM test ORDER BY (data->>'age')::numeric ASC;

-- does not work
/*
ERROR:  CASE types text and numeric cannot be matched
LINE 5:         WHEN 'number' THEN (data->>'age')::numeric
*/
SELECT data->>'name' as name, data->>'age' as age 
FROM test
ORDER BY
    CASE jsonb_typeof(data->'age')
        WHEN 'number' THEN (data->>'age')::numeric
        ELSE data->>'age'
    END
ASC;

(实际的字段名会从代码中注入到查询中)

【问题讨论】:

    标签: postgresql jsonb


    【解决方案1】:

    在某些情况下,您可以直接通过data->'age'data->'name' 订购,而无需强制转换。

    (note the use of the -> operator which returns a JSONB value, instead of the ->> which always returns text)

    This seems to work in both cases:

    SELECT data->>'name' as name, data->>'age' as age 
    FROM test
    ORDER BY data->'age' ASC;
    -- name     age
    -- cc         1
    -- b          2
    -- d          4
    -- a         33
    
    SELECT data->>'name' as name, data->>'age' as age 
    FROM test
    ORDER BY data->'name' ASC;
    -- name     age
    -- a         33
    -- b          2
    -- cc         1
    -- d          4
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-12
      • 1970-01-01
      • 2021-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-20
      相关资源
      最近更新 更多