অ্যারেগুলিতে জেসোনব কী সাজানোর ক্রমটি কাস্টমাইজ করুন


9

কিছু ডেটা সহ আমার পোস্টগ্রিজ এসকিউএলে একটি টেবিল রয়েছে:

create table t2 (
    key jsonb,
    value jsonb
);

INSERT INTO t2(key, value)
 VALUES
 ('1', '"test 1"')
,('2', '"test 2"')
,('3', '"test 3"')
,('[]', '"test 4"')
,('[1]', '"test 5"')
,('[2]', '"test 6"')
,('[3]', '"test 7"')
,('[1, 2]', '"test 8"')
,('[1, 2, 3]', '"test 9"')
,('[1, 3]', '"test 10"')
,('[1,2,4]', '"test 11"')
,('[1, 2,4]', '"test 12"')
,('[1,3,13]', '"test 13"')
,('[1, 2, 15]', '"test 15"');

এবং আমি এই সারিগুলি এর মতো সাজানোর চেষ্টা করি:

SELECT key FROM t2 order by key;

ফলাফল হলো:

[]
1
2
3
[1]
[2] <==
[3] <==
[1, 2]
[1, 3] <==
[1, 2, 3]
[1, 2, 4]
[1, 2, 4]
[1, 2, 15]
[1, 3, 13]

তবে আমার যা দরকার তা হ'ল:

[]
1
2
3
[1]
[1, 2]
[1, 2, 3]
[1, 2, 4]
[1, 2, 4]
[1, 2, 15]
[1, 3] <==
[1, 3, 13]
[2] <==
[3] <==

এটি অর্জন করার কোন উপায় আছে?


তাহলে আপনার কি এখানে উত্তর আছে?
এরউইন ব্র্যান্ডসেটেটার

উত্তর:


8

প্রথমত, আপনার প্রশ্ন পাশাপাশি আপনার কলামের নাম "key"বিভ্রান্তিকর। কলাম কীটিতে কোনও JSON কী নেই , কেবলমাত্র মান । অন্যথায় আমরা jsonb_object_keys(jsonb)কীগুলি বের করতে ফাংশনটি ব্যবহার করতে পারি , তবে এটি তেমন নয়।

ধরে নিলাম আপনার সমস্ত JSON অ্যারে হয় ফাঁকা হয় বা প্রদর্শিত হিসাবে পূর্ণসংখ্যার সংখ্যা ধরে রাখে। এবং স্কেলারের মানগুলি (অ-অ্যারে) এছাড়াও পূর্ণসংখ্যা হয়।

আপনার প্রাথমিক সাজানোর ক্রম পোস্টগ্রিস integer(বা numeric) অ্যারেগুলির সাথে কাজ করবে । অ্যারেগুলিকে পোস্টগ্র্রেসে রূপান্তর করতে আমি এই ছোট সহায়ক সহায়ক ফাংশনটি ব্যবহার করি :jsonbint[]

CREATE OR REPLACE FUNCTION jsonb_arr2int_arr(_js jsonb)
   RETURNS int[] LANGUAGE sql IMMUTABLE AS
'SELECT ARRAY(SELECT j::int FROM jsonb_array_elements_text(_js) j)';

ব্যাখ্যা:

তারপরে jsonb_typeof(jsonb)পৌঁছানোর জন্য যুক্ত করুন:

SELECT key
FROM   t2
ORDER  BY key <> '[]'             -- special case for empty array
        , jsonb_typeof(key) DESC  -- 'number' before 'array'
        , CASE jsonb_typeof(key)  -- sort arrays as converted int[]
            WHEN 'array'  THEN jsonb_arr2int_arr(key)
            WHEN 'number' THEN ARRAY[key::text::int]
          END;

কাঙ্ক্ষিত ফলাফলটি হুবহু উত্পন্ন করে।

কেন?

jsonbব্যাখ্যার জন্য ম্যানুয়াল :

btreeজন্য ক্রম jsonbdatums মহান সুদ কদাপি, কিন্তু সম্পূর্ণতার জন্য এটি হল:

Object > Array > Boolean > Number > String > Null
Object with n pairs > object with n - 1 pairs
Array with n elements > array with n - 1 elements

সমান সংখ্যক জোড় যুক্ত বস্তুগুলি ক্রমের সাথে তুলনা করা হয়:

key-1, value-1, key-2 ...

নোট করুন যে অবজেক্ট কীগুলি তাদের স্টোরেজ ক্রমের সাথে তুলনা করা হয়েছে; বিশেষত, যেহেতু দীর্ঘ চাবিগুলির আগে সংক্ষিপ্ত কীগুলি সংরক্ষণ করা হয়, এর ফলে ফলাফলগুলি অনর্থক হতে পারে যেমন:

{ "aa": 1, "c": 1} > {"b": 1, "d": 1}

একইভাবে, সমান সংখ্যক উপাদানের সাথে অ্যারেগুলি ক্রমে তুলনা করা হয়:

element-1, element-2 ...

বোল্ড জোর আমার।
এজন্যই jsonb '[2]' < jsonb '[1, 2]'
তবে পোস্টগ্র্রেস অ্যারেগুলি কেবলমাত্র উপাদান দ্বারা উপাদান সাজান: '{2}'::int[] > '{1, 2}'- ঠিক আপনি যা খুঁজছিলেন তাই।


0

আপনার ফলাফলটি জসন সংখ্যার পূর্ণসংখ্যার মানগুলি দ্বারা অর্ডার করতে সমস্যাটি উল্লেখ করে। চেষ্টা করুন:

select myjson from mytable order by (myjson->>'some_int')::int;

আপনার ক্ষেত্রে এটি অর্ডারিং কীটির জন্য একটি অ্যারে বলে মনে হচ্ছে। সুতরাং প্রথমে আপনার "কী" ক্ষেত্রে মানগুলিকে একত্রিত করার চেষ্টা করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.