পোস্টগ্রিসএসকিউএলে জেএসএনবি-কে জিজ্ঞাসাবাদ করা হচ্ছে


14

আমার একটি টেবিল personsরয়েছে, যার মধ্যে দুটি কলাম রয়েছে, একটি idএবং একটি জেএসওএনবি ভিত্তিক dataকলাম (এই টেবিলটি পোস্টগ্র্রেএসকিউএলএর জেএসওএন সমর্থন সমর্থন করে প্রদর্শনের উদ্দেশ্যে তৈরি করা হয়েছে)।

এখন, এটিতে দুটি রেকর্ড রয়েছে বলে মনে করা হচ্ছে:

1, { name: 'John', age: 30 }
2, { name: 'Jane', age: 20 }

এখন, অনুমিত হয়ে আমি 25 বছরেরও বেশি বয়স্ক প্রত্যেক ব্যক্তির নাম পেতে চাই I আমি যা চেষ্টা করেছি তা হ'ল:

select data->'name' as name from persons where data->'age' > 25

দুর্ভাগ্যক্রমে, এর ফলে একটি ত্রুটি হয়। আমি এর ->>পরিবর্তে ব্যবহার করে এটি সমাধান করতে পারি ->, তবে তারপরে তুলনাগুলি আর প্রত্যাশার মতো কাজ করে না, যেহেতু সংখ্যার তুলনা করা হয় না, তবে স্ট্রিং হিসাবে তাদের উপস্থাপনা:

select data->'name' as name from persons where data->>'age' > '25'

আমি তখন বুঝতে পেরেছিলাম যে আমি আসলে ব্যবহার করে ->এবং একটি কাস্ট করে সমস্যার সমাধান করতে পারি int:

select data->'name' as name from persons where cast(data->'age' as int) > 25

এটি কাজ করে, তবে এটি এতটা সুন্দর নয় যে আমাকে প্রকৃত প্রকারটি জানতে হবে ( ageজেএসওএন নথির ধরণটি numberযাইহোক, তাই পোস্টগ্র্রেএসকিউএল কেন এটি নিজেই খুঁজে বের করতে পারে না?)।

আমি তখন বুঝতে পেরেছি যে আমি যদি সিনট্যাক্সটি textব্যবহার করে ম্যানুয়ালি রূপান্তর করি তবে ::সবকিছুই প্রত্যাশার মতো কাজ করে - যদিও আমরা এখন আবার স্ট্রিংয়ের তুলনা করছি।

select data->'name' as name from persons where data->'age'::text > '25'

আমি যদি বয়সের পরিবর্তে নাম দিয়ে চেষ্টা করে দেখি তবে এটি কার্যকর হয় না:

select data->'name' as name from persons where data->'name'::text > 'Jenny'

এটি একটি ত্রুটিতে ফলাফল:

টাইপ জসনের জন্য অবৈধ ইনপুট সিনট্যাক্স

খুব সম্ভবত স্পষ্টতই, আমি এখানে কিছু পাই না। দুর্ভাগ্যক্রমে, পোস্টগ্র্রেএসকিউএল সহ জেএসএন ব্যবহার করার কোনও বাস্তব-বিশ্বের উদাহরণ খুঁজে পাওয়া বেশ কঠিন।

কোন ইঙ্গিত?


1
ইন data->'name'::text, আপনি 'name'টেক্সটে স্ট্রিং কাস্ট করছেন, ফলাফল নয়। আপনি একটি ত্রুটি তুলনায় পাবেন না '25'কারণ 25একটি বৈধ JSON আক্ষরিক হয়; তবে Jennyতা নয় (যদিও "Jenny"হবে)।
চিরলু

ধন্যবাদ, এটি সমাধান :-)। আমি বিভ্রান্ত 'Jenny'সঙ্গে '"Jenny"'
গলো রডেন

উত্তর:


15

এটি কাজ করে না কারণ এটিতে কোনও jsonbমূল্য দেওয়ার চেষ্টা করা হচ্ছে integer

select data->'name' as name from persons where cast(data->'age' as int) > 25

এটি আসলে কাজ করবে:

SELECT data->'name' AS name FROM persons WHERE cast(data->>'age' AS int) > 25;

বা সংক্ষিপ্ত:

SELECT data->'name' AS name FROM persons WHERE (data->>'age')::int > 25;

এবং এই:

SELECT data->'name' AS name FROM persons WHERE data->>'name' > 'Jenny';

দুটি অপারেটর ->এবং->> এবং অপারেটরের অগ্রাধিকারের সাথে বিভ্রান্তির মতো মনে হচ্ছে । Cast ::ালাই json (খ) অপারেটরগুলির চেয়ে শক্তিশালী বাঁধাই করে।

চিত্রে গতিশীল টাইপ করুন

এটি আপনার প্রশ্নের আরও আকর্ষণীয় অংশ:

জেএসওএন নথিতে বয়সের ধরণ যাই হোক না কেন সংখ্যা, সুতরাং কেন পোস্টগ্র্যাসকিউএল নিজেই এটি নির্ধারণ করতে পারে না?

এসকিউএল হ'ল একটি কঠোরভাবে টাইপ করা ভাষা, এটি একই অভিব্যক্তিটিকে integerএক সারিতে এবং textপরের দিকে মূল্যায়ন করতে দেয় না । তবে যেহেতু আপনি কেবল booleanপরীক্ষার ফলাফলের প্রতি আগ্রহী তাই আপনি এই নিষেধাজ্ঞার সাথে এমন CASEঅভিব্যক্তিটি পেতে পারেন যা ফলাফলের উপর নির্ভর করে কাঁটাচামচ করে jsonb_typeof():

SELECT data->'name'
FROM   persons
WHERE  CASE jsonb_typeof(data->'age')
        WHEN 'number'  THEN (data->>'age')::numeric > '25' -- treated as numeric
        WHEN 'string'  THEN data->>'age' > 'age_level_3'   -- treated as text
        WHEN 'boolean' THEN (data->>'age')::bool           -- use boolean directly (example)
        ELSE FALSE                                         -- remaining: array, object, null
       END;

>অপারেটরের ডানদিকে একটি টাইপযুক্ত স্ট্রিং আক্ষরিক বামে স্বয়ংক্রিয়ভাবে মান সম্পর্কিত প্রকারের সাথে জোর করা হয়। আপনি যদি সেখানে কোনও টাইপ করা মান রেখে থাকেন তবে টাইপের সাথে মিল রাখতে হবে বা আপনাকে এটি স্পষ্টভাবে কাস্ট করতে হবে - যতক্ষণ না সিস্টেমে পর্যাপ্ত অন্তর্নিহিত কাস্ট নিবন্ধিত থাকে।

আপনি যদি জানেন যে সমস্ত সংখ্যাসূচক মানগুলি আসলে integer, আপনি এটিও করতে পারেন:

... (data->>'age')::int > 25 ...

উদাহরণস্বরূপ উপরোক্ত তুলনায় সিলেক্টেমি কোর এক্সপ্রেশনটি কী? s = সিলেক্ট করুন ([ইস্যু])। যেখানে (ইস্যু। সি। আইডি == মিড) ) ... এখানে issues.c.data jsonb ডাটা টাইপ এবং পূর্ণসংখ্যা ধরনের mtypes.c.id সঙ্গে তুলনা করা হচ্ছে
user956424
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.