ওরাকলে একাধিক সারি থেকে কলামের মানগুলি সংলগ্ন করতে এসকিউএল ক্যোয়ারী


169

একাধিক সারি থেকে কলাম মানগুলি সংযুক্ত করতে এসকিউএল তৈরি করা সম্ভব হবে?

নিচেরটি একটি উদাহরণ:

টেবিল এ

PID,
একজন
বি
সি

টেবিল বি

পিআইডি SEQ ডেস্ক

এ 1 আছে
একটি 2 দুর্দান্ত
একটি 3 দিন।
বি 1 সুন্দর কাজ।
সি 1 হ্যাঁ
সি 2 আমরা পারি 
সি 3 কর 
সি 4 এই কাজ!

এসকিউএল এর আউটপুট হওয়া উচিত -

পিআইডি ডেস্ক
খুব সুন্দর দিন কাটুক
বি সুন্দর কাজ।
সি হ্যাঁ আমরা এই কাজটি করতে পারি!

সুতরাং মূলত আউট টেবিলের জন্য ডেস্ক কলামটি টেবিল বি থেকে এসইকিউ মানগুলির সংমিশ্রণ?

এসকিউএল কোন সহায়তা?


উদাহরণস্বরূপ দেখুন: halisway.blogspot.com/2006/08/…
Andomar

দয়া করে এই সমাধানটি দেখুন । এটি আপনার কাজে আসবে।
জিনেশ উওয়ান্তাভিদা

উত্তর:


237

আপনার কী সংস্করণ রয়েছে তার উপর নির্ভর করে কয়েকটি উপায় রয়েছে - স্ট্রিং অগ্রিগেশন কৌশলগুলিতে ওরাকল ডকুমেন্টেশন দেখুন । একটি খুব সাধারণ ব্যবহার করা হয় LISTAGG:

SELECT pid, LISTAGG(Desc, ' ') WITHIN GROUP (ORDER BY seq) AS description
FROM B GROUP BY pid;

তারপরে আপনি যা চান Aতা চয়ন করতে যোগ দিন pids

দ্রষ্টব্য: বাক্সের বাইরে, LISTAGGকেবল VARCHAR2কলামগুলির সাথে সঠিকভাবে কাজ করে ।


2
ওরাকল 10 জি এর জন্য ডাব্লুএম_কনক্যাট () ব্যবহার করে কমা দ্বারা বিভাজনযুক্ত ক্রম সংখ্যাটির আরোহী ক্রমে পাঠ্যকে সম্মতি জানানো হয়, আমরা কি অন্য কিছুর মাধ্যমে সীমানা অবলম্বন করতে পারি?
জাগমোট

19

এছাড়াও একটি আছে XMLAGG ফাংশনও রয়েছে, যা ১১.২-এর পূর্ববর্তী সংস্করণগুলিতে কাজ করে। কারণ WM_CONCATহয় অনথিভুক্ত এবং ওরাকল দ্বারা সমর্থিত , এটা উৎপাদন ব্যবস্থা এটি ব্যবহার করতে না পরামর্শ দেওয়া হচ্ছে।

সঙ্গে XMLAGGআপনি নিম্নলিখিতটি করতে পারেন :

SELECT XMLAGG(XMLELEMENT(E,ename||',')).EXTRACT('//text()') "Result" 
FROM employee_names

এটি কি করে

  • এর মান রাখুন enameemployee_namesএকটি এক্সএমএল উপাদান (ট্যাগ ই সহ) টেবিল থেকে কলামের (কমা দিয়ে সংযুক্ত) রাখুন
  • এটির পাঠ্য বের করুন
  • এক্সএমএল একত্রিত করুন (এটি একত্রিত করুন)
  • ফলস্বরূপ কলামটি "ফলাফল" কল করুন

এক্সএমএলজিজি ওরাকল 12.2 এ কাজ করে। তদুপরি, এক্সএলএমএজিজি খুব দীর্ঘ স্ট্রিংগুলি সংহত করতে দেয় যা লিস্টাগজি তাদের চূড়ান্ত দৈর্ঘ্যের কারণে নাও পারে।
মার্কো

13

এসকিউএল মডেল ধারা সহ:

SQL> select pid
  2       , ltrim(sentence) sentence
  3    from ( select pid
  4                , seq
  5                , sentence
  6             from b
  7            model
  8                  partition by (pid)
  9                  dimension by (seq)
 10                  measures (descr,cast(null as varchar2(100)) as sentence)
 11                  ( sentence[any] order by seq desc
 12                    = descr[cv()] || ' ' || sentence[cv()+1]
 13                  )
 14         )
 15   where seq = 1
 16  /

P SENTENCE
- ---------------------------------------------------------------------------
A Have a nice day
B Nice Work.
C Yes we can do this work!

3 rows selected.

আমি এখানে এই সম্পর্কে লিখেছি । এবং যদি আপনি ওটিএন-থ্রেডের লিঙ্কটি অনুসরণ করেন তবে আপনি পারফরম্যান্স তুলনা সহ আরও কিছু পাবেন।


10

লিস্টাগজি অ্যানালিটিক ফাংশনটি ওরাকল 11 জি রিলিজ 2 এ চালু হয়েছিল , এটি সামগ্রিক স্ট্রিংগুলিকে খুব সহজ করে তুলেছিল । আপনি যদি 11 জি রিলিজ 2 ব্যবহার করে থাকেন তবে আপনার স্ট্রিং একীকরণের জন্য এই ফাংশনটি ব্যবহার করা উচিত। স্ট্রিং কনকেন্টেশন সম্পর্কে আরও তথ্যের জন্য দয়া করে নীচে url দেখুন।

http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php

স্ট্রিং সংযোগ


8

উত্তরগুলির বেশিরভাগ হিসাবে বোঝা যায়, LISTAGGএটি হ'ল সুস্পষ্ট বিকল্প। যাইহোক, এর সাথে একটি বিরক্তিকর দিকটি LISTAGGহ'ল যদি সংক্ষিপ্ত স্ট্রিংয়ের মোট দৈর্ঘ্য 4000 টি অক্ষর ( VARCHAR2এসকিউএল এর সীমা ) ছাড়িয়ে যায় তবে নীচের ত্রুটিটি নিক্ষেপ করা হয়, যা 12.1 অবধি ওরাকল সংস্করণগুলিতে পরিচালনা করা কঠিন is

ORA-01489: স্ট্রিং কনটেনটেশনের ফলাফল খুব দীর্ঘ

12 সিআর 2 তে যুক্ত হওয়া একটি নতুন বৈশিষ্ট্য হ'ল এর ON OVERFLOWধারা LISTAGG। এই ধারাটি সহ ক্যোয়ারীটি এমন দেখাচ্ছে:

SELECT pid, LISTAGG(Desc, ' ' on overflow truncate) WITHIN GROUP (ORDER BY seq) AS desc
FROM B GROUP BY pid;

উপরেরটি আউটপুটটিকে 4000 টি অক্ষরে সীমাবদ্ধ করবে তবে ORA-01489ত্রুটিটি ছুঁড়ে দেবে না ।

এগুলি ON OVERFLOWধারাটির অতিরিক্ত কয়েকটি বিকল্প রয়েছে :

  • ON OVERFLOW TRUNCATE 'Contd..' : এটি 'Contd..'স্ট্রিংয়ের শেষে প্রদর্শিত হবে (ডিফল্ট হয় ...)
  • ON OVERFLOW TRUNCATE '' : এটি কোনও সমাপ্তি স্ট্রিং ছাড়াই 4000 অক্ষর প্রদর্শন করবে।
  • ON OVERFLOW TRUNCATE WITH COUNT: এটি সমাপ্তি অক্ষরগুলির শেষে অক্ষরের মোট সংখ্যা প্রদর্শন করবে। যেমন: - ' ...(5512)'
  • ON OVERFLOW ERROR: আপনি যদি ত্রুটিটি LISTAGGব্যর্থ হওয়ার প্রত্যাশা করেন ORA-01489(যা যাইহোক ডিফল্ট)।

6

যাদের অবশ্যই ওরাকল 9 আই (বা তার আগে) ব্যবহার করে এই সমস্যাটি সমাধান করতে হবে তাদের জন্য আপনার সম্ভবত SYS_CONNECT_BY_PATH ব্যবহার করা প্রয়োজন, যেহেতু LISTAGG উপলভ্য নয়।

ওপিকে উত্তর দেওয়ার জন্য, নিম্নলিখিত কোয়েরিটি সারণি এ থেকে পিআইডি প্রদর্শন করবে এবং সারণি বি থেকে সমস্ত ডিইএসসি কলামকে সম্মতি জানাবে:

SELECT pid, SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
       SELECT ROW_NUMBER () OVER (PARTITION BY pid ORDER BY pid, seq) rnum, pid, description
       FROM (
              SELECT a.pid, seq, description
              FROM table_a a, table_b b
              WHERE a.pid = b.pid(+)
             )
      )
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1 AND PRIOR pid = pid
GROUP BY pid
ORDER BY pid;

এমন উদাহরণগুলিও থাকতে পারে যেখানে কী এবং মানগুলি সমস্ত এক টেবিলে থাকে। যেখানে সারণি A নেই সেখানে নিম্নলিখিত কোয়েরিটি ব্যবহার করা যেতে পারে এবং কেবল সারণি বি বিদ্যমান রয়েছে:

SELECT pid, SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
       SELECT ROW_NUMBER () OVER (PARTITION BY pid ORDER BY pid, seq) rnum, pid, description
       FROM (
              SELECT pid, seq, description
              FROM table_b
             )
      )
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1 AND PRIOR pid = pid
GROUP BY pid
ORDER BY pid;

সমস্ত মান পছন্দসই হিসাবে পুনরায় সাজানো যেতে পারে। পৃথক সংক্ষিপ্ত বিবরণগুলি বিভাগ দ্বারা পার্টিশনে পুনরায় সাজানো যেতে পারে, এবং পিআইডিগুলির তালিকা চূড়ান্ত অর্ডারের দ্বারা ধারা অনুসারে পুনরায় সাজানো যেতে পারে।


পর্যায়ক্রমে: এমন সময়গুলি হতে পারে যখন আপনি পুরো টেবিল থেকে সমস্ত মানকে এক সারিতে যুক্ত করতে চান।

এখানে মূল ধারণাটি বর্ণনাকারীর দলটিকে সম্মিলিত করার জন্য একটি কৃত্রিম মান ব্যবহার করছে।

নিম্নলিখিত ক্যোয়ারিতে, ধ্রুব স্ট্রিং '1' ব্যবহৃত হয়, তবে যে কোনও মান কাজ করবে:

SELECT SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
       SELECT ROW_NUMBER () OVER (PARTITION BY unique_id ORDER BY pid, seq) rnum, description
       FROM (
              SELECT '1' unique_id, b.pid, b.seq, b.description
              FROM table_b b
             )
      )
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1;

পৃথক সংক্ষিপ্ত বিবরণগুলি বিভাগ দ্বারা পার্টিশনে পুনরায় সাজানো যেতে পারে।

এই পৃষ্ঠার অন্যান্য বেশ কয়েকটি জবাবও এই অত্যন্ত সহায়ক উল্লেখটি উল্লেখ করেছে: https://oracle-base.com/articles/misc/string-aggregation-techniques


3
  1. তালিকা বাছাই করা আবশ্যক হলে সেরা পারফরম্যান্স সরবরাহ করে (00: 00: 05.85)

    SELECT pid, LISTAGG(Desc, ' ') WITHIN GROUP (ORDER BY seq) AS description FROM B GROUP BY pid;

  2. বাছাইয়ের প্রয়োজন না হলে সর্বাধিক পারফরম্যান্স সরবরাহ করুন (00: 00: 02.90):

    SELECT pid, TO_STRING(CAST(COLLECT(Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid;

  3. অর্ডার সহ সংগ্রহ করুন কিছুটা ধীর (00: 00: 07.08):

    SELECT pid, TO_STRING(CAST(COLLECT(Desc ORDER BY Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid;

অন্যান্য সমস্ত কৌশল ধীর ছিল।


1
আপনার উত্তরের বিস্তারিত জানাতে এটি সহায়ক হবে।
জন সারেল

জন, আমি আর্টিকেলটি থেকে পুনরাবৃত্তি করতে চাইনি তবে সংক্ষেপে এই ফলাফলগুলি: ১. বাছাই করা আবশ্যক হলে লিস্টাগজি সেরা পারফরম্যান্স সরবরাহ করে (00: 00: 05.85) ২. বাছাই না করা হলে সেরা পারফরম্যান্স সরবরাহ করে প্রয়োজনীয় (00: 00: 02.90): পিড নির্বাচন করুন, টু_স্ট্রিং (ক্যাসেট (সংগ্রহ করুন (বর্ণনামূলকভাবে (varchar2_ntt)) পিআইডি দ্বারা বি গ্রুপ থেকে AS; ৩. অর্ডার সহ সংগ্রহ করুন কিছুটা ধীর গতিতে (00: 00: 07.08): পিড নির্বাচন করুন, ট্যাস্ট্রিং করুন (ক্যাসেট (সংগ্রহ করুন (ডেস্কের অর্ডারের মাধ্যমে বর্ণ) AS varchar2_ntt)) পিআইডি দ্বারা বি গ্রুপ থেকে; অন্যান্য সমস্ত কৌশল ধীর ছিল।
মিশো

1
প্রাসঙ্গিক তথ্য অন্তর্ভুক্ত করতে আপনি কেবল নিজের উত্তরটি সম্পাদনা করতে পারেন।
জন সোর্েল

আমি সম্পাদনায় অনেক দেরি করেছি এবং সে কারণেই আমি এটি আবার যুক্ত করেছি। দুঃখিত আমি এখানে নতুন এবং এটির ঝুলন্ত পেতে শুরু করি।
মিশো

1

আপনি একটি নির্বাচিত ক্যোয়ারী চালানোর আগে এটি চালান:

SET SERVEROUT ON SIZE 6000

SELECT XMLAGG(XMLELEMENT(E,SUPLR_SUPLR_ID||',')).EXTRACT('//text()') "SUPPLIER" 
FROM SUPPLIERS;


-3

আপনি যেখানে নির্বাচন করতে চান সেখানে নির্বাচন করুন, একটি এসকিউএল ফাংশন কল করুন।

উদাহরণ স্বরূপ:

select PID, dbo.MyConcat(PID)
   from TableA;

তারপরে এসকিউএল ফাংশনের জন্য:

Function MyConcat(@PID varchar(10))
returns varchar(1000)
as
begin

declare @x varchar(1000);

select @x = isnull(@x +',', @x, @x +',') + Desc
  from TableB
    where PID = @PID;

return @x;

end

ফাংশন শিরোলেখ সিনট্যাক্সটি ভুল হতে পারে তবে নীতিটি কাজ করে।


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