Json_agg এর ভিতরে কলাম নির্বাচন করুন


21

আমার মত একটি প্রশ্ন আছে:

SELECT a.id, a.name, json_agg(b.*) as "item"
  FROM a
  JOIN b ON b.item_id = a.id
 GROUP BY a.id, a.name;

আমি কীভাবে কলামগুলি নির্বাচন করতে পারি bযাতে আমার b.item_idজেএসওএন অবজেক্টে নেই?

আমি সম্পর্কে পড়েছি ROW, তবে এটি একটি JSON অবজেক্টের মতো করে:

{"f1": "Foo", "f2": "Bar"}

একবারে যথাযথ কলামের চাবিগুলি মেলে জেএসএন অবজেক্টটি পুনরায় তৈরি করতে হবে। আমি এড়াতে এবং মূল কলামের নাম রাখতে চাই।

উত্তর:


50

দুর্ভাগ্যক্রমে, এসকিউএল সিন্টেক্সে "এই এক কলাম ব্যতীত সমস্ত কলাম" বলার বিধান নেই । সারি ধরণের এক্সপ্রেশনটিতে থাকা কলামগুলির অবশিষ্ট তালিকাটি বানান করে আপনি আপনার লক্ষ্য অর্জন করতে পারেন :

SELECT a.id, a.name
     , json_agg((b.col1, b.col2, b.col3)) AS item
FROM   a
JOIN   b ON b.item_id = a.id
GROUP  BY a.id, a.name;

যে অনেক বেশী সুনিদৃষ্ট ফর্ম জন্য ছোট: । ROW(b.col1, b.col2, b.col3)

যাইহোক, কলামের নামগুলি সারি-ধরণের এক্সপ্রেশনগুলিতে সংরক্ষণ করা হয় না। আপনি JSON অবজেক্টে জেনেরিক কী নামগুলি পান। মূল কলামের নাম সংরক্ষণের জন্য আমি 3 টি বিকল্প দেখতে পাচ্ছি:

1. নিবন্ধিত টাইপ কাস্ট

একটি সুপরিচিত (নিবন্ধিত) সারি প্রকারে কাস্ট করুন। প্রতিটি বিদ্যমান টেবিল বা দেখার জন্য বা স্পষ্ট CREATE TYPEবক্তব্য সহ একটি প্রকার নিবন্ধভুক্ত । আপনি অ্যাডহক সমাধানের জন্য একটি অস্থায়ী টেবিল ব্যবহার করতে পারেন (অধিবেশনটির সময়কালের জন্য জীবন):

CREATE TEMP TABLE x (col1 int, col2 text, col3 date);  -- use adequate data types!

SELECT a.id, a.name
     , json_agg((b.col1, b.col2, b.col3)::x) AS item
FROM   a
JOIN   b ON b.item_id = a.id
GROUP  BY a.id, a.name;

২. একটি সাবলেট ব্যবহার করুন

উদ্ভূত টেবিলটি তৈরি করতে একটি সাবলেট ব্যবহার করুন এবং পুরো টেবিলটি রেফারেন্স করুন । এটিতে কলামের নামও রয়েছে। এটি আরও ভার্বোজ, তবে আপনার নিবন্ধিত প্রকারের দরকার নেই:

SELECT a.id, a.name
     , json_agg((SELECT x FROM (SELECT b.col1, b.col2, b.col3) AS x)) AS item
FROM   a
JOIN   b ON b.item_id = a.id
GROUP  BY a.id, a.name;

3. json_build_object()পোস্টগ্রিস 9.4 বা তারপরে

SELECT a.id, a.name
     , json_agg(json_build_object('col1', b.col1, 'col2', b.col2, 'col3', b.col3)) AS item
FROM   a
JOIN   b ON b.item_id = a.id
GROUP  BY a.id, a.name;

সম্পর্কিত:

jsonbসম্পর্কিত ফাংশন jsonb_agg()এবং জন্য একই jsonb_build_object()

জন্য Postgres 9.5 বা পরবর্তী তাও দেখতে a_horse এর উত্তর একটি নতুন খাটো সিনট্যাক্স বৈকল্পিক সঙ্গে Postgres যোগ বিয়োগ অপারেটর -জন্যjsonb বলতে "এই একটা চাবি ছাড়া সমস্ত চাবি"
যেহেতু পোস্টগ্র্রেস 10 "বেশ কয়েকটি কী বাদে" একই অপারেটরের সাথে text[]দ্বিতীয় অপারেন্ড হিসাবে গ্রহণ হিসাবে প্রয়োগ করা হয় - যেমন মল্ট মন্তব্য করেছে।


1
> বা কয়েকটি কী নোট করুন যে json (b) -text [] 10 থেকে শুরু হয়
21 পয়েন্ট

সমাধান 3 একটি কবজ মত আমার জন্য কাজ করে!
লুইজ ফার্নান্দো দা সিলভা

17

9.6 দিয়ে শুরু করে আপনি -JSONB থেকে কীটি সরাতে কেবল ব্যবহার করতে পারেন:

SELECT a.id, a.name, jsonb_agg(to_jsonb(b) - 'item_id') as "item"
FROM a
  JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;

to_jsonb(b)পুরো সারিটি রূপান্তরিত করবে এবং - 'item_id'তারপরে নামেরটির সাথে কীটি মুছে ফেলা হবে তার item_idফলস্বরূপ একত্রিত হবে।


এই নতুন বৈশিষ্ট্যগুলি মনে হয় ওপি যা আশা করেছিল। আমি আমার উত্তরের একটি লিঙ্ক যুক্ত করেছি।
এরউইন ব্র্যান্ডস্টেটার

আমি যখন সাব-ইলেক্ট বৈকল্পিকটি চেষ্টা করেছি, তখন আমি json_aggফাংশন সম্পর্কিত একটি ত্রুটি পেয়েছি :function json_agg(record) does not exist
কাঠামো

@ সংশ্লেষ: তারপরে আপনি
পোস্টগ্র্রেস

আসলে সমস্যা ছিল। V9.2 এ কলামগুলি ফিল্টার করার কোনও উপায় আছে কি?
কাঠামো

8

আপনি সাবকিউরিগুলি ব্যবহার করে এটি গোষ্ঠীবিহীনভাবে করতে পারেন

SELECT 
  a.id, a.name, 
  ( 
    SELECT json_agg(item)
    FROM (
      SELECT b.c1 AS x, b.c2 AS y 
      FROM b WHERE b.item_id = a.id
    ) item
  ) AS items
FROM a;

আয়

{
  id: 1,
  name: "thing one",
  items:[
    { x: "child1", y: "child1 col2"},
    { x: "child2", y: "child2 col2"}
  ]
}

জন অ্যাটেনের এই নিবন্ধটি সত্যিই আকর্ষণীয় এবং আরও বিশদ রয়েছে


2

আমি খুঁজে পেয়েছি যে JSON তৈরি করা ভাল, তারপরে এটি একত্রিত করুন। যেমন

with base as (
select a, b, ('{"ecks":"' || to_json(x) || '","wai":"' || to_json(y) || '","zee":"' || to_json(z) || '"}"')::json c
) select (a, b, array_to_json(array_agg(c)) as c)

আপনি যদি সিটিই পছন্দ না করেন (বা এটি ব্যবহারের কারণে পারফরম্যান্সে সমস্যা আছে) তবে এটি সাবকিউরি হিসাবে করা যেতে পারে Note

এছাড়াও নোট করুন, আপনি যদি এটি অনেক কিছু করতে চলেছেন তবে কোডটি আরও পরিষ্কার দেখায় তাই আপনার জন্য কী-মান জোড়গুলি মোড়ানোর জন্য একটি ফাংশন তৈরি করা উপকারী হতে পারে। আপনি আপনার ফাংশনটি পাস করবেন (উদাহরণস্বরূপ) 'ecks', 'x'এবং এটি ফিরে আসবে "ecks": "x"


1

যদিও এখনও সমস্ত কলামগুলি json_agg(to_json(b.col_1, b.col_2, b.col_3 ...))বাদে কিছুটা বেছে নেওয়ার উপায় নেই তবে আপনি বিন্যাসে প্রতিটি জসনের একটি জসন অ্যারে পেতে ব্যবহার করতে পারেন {"col_1":"col_1 value", ...}

সুতরাং ক্যোয়ারীটি এমন কিছু দেখাচ্ছে:

SELECT a.id, a.name, json_agg(to_json(b.col_1,b.col_2,b.col_3...)) as item
  FROM a
  JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;

এবং সারি হিসাবে ফিরে আসবে:

id, name, item
8, the_name, [{"col_1":"value_1","col_2":"value_2","col_3":"value_3"...}, {"col_1":"value_1.2","col_2":"value_2.2","col_3":"value_3.2"...},...]
9, the_next_name, [{"col_1":"value_1.3","col_2":"value_2.3","col_3":"value_3.3"...},   {"col_1":"value_1.4","col_2":"value_2.4","col_3":"value_3.4"...},...]
...

(আমি এখন পোস্টগ্রিসে 9.5.3 এ আছি এবং এই সমর্থনটি কখন যুক্ত হয়েছিল 100% নিশ্চিত নয়))


1

আপনি ব্যবহার করতে পারেন json_build_objectএই মত

SELECT 
  a.id, 
  a.name,
  json_agg(json_build_object('col1', b.col1, 'col2', b.col2) AS item
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.