তালিকাগুলিতে নকলকে বাদ দিন (ওরাকল)


44

ওরাকল ১১.২ এর আগে আমি একটি কলামকে এক সারি করে বোঝাতে একটি কাস্টম সমষ্টিগত ফাংশন ব্যবহার করছিলাম। 11.2 LISTAGGফাংশনটি যুক্ত করেছে , তাই আমি পরিবর্তে এটি ব্যবহার করার চেষ্টা করছি। আমার সমস্যাটি হ'ল আমাকে ফলাফলগুলিতে নকলগুলি সরিয়ে ফেলতে হবে এবং এটি করতে সক্ষম হবে বলে মনে হয় না।

এখানে একটি উদাহরণ।

CREATE TABLE ListAggTest AS (
  SELECT rownum Num1, DECODE(rownum,1,'2',to_char(rownum)) Num2 FROM dual 
     CONNECT BY rownum<=6
  );
SELECT * FROM ListAggTest;
      NUM1 NUM2
---------- ---------------------
         1 2
         2 2                    << Duplicate 2
         3 3
         4 4
         5 5
         6 6

আমি যা দেখতে চাই তা হ'ল:

      NUM1 NUM2S
---------- --------------------
         1 2-3-4-5-6
         2 2-3-4-5-6
         3 2-3-4-5-6
         4 2-3-4-5-6
         5 2-3-4-5-6
         6 2-3-4-5-6

এখানে এমন একটি listaggসংস্করণ রয়েছে যা কাছাকাছি থাকলেও সদৃশগুলি মুছে দেয় না।

SELECT Num1, listagg(Num2,'-') WITHIN GROUP (ORDER BY NULL) OVER () Num2s 
FROM ListAggTest;

আমার একটি সমাধান আছে, তবে এটি কাস্টম সমষ্টিগত ক্রিয়াকলাপটি চালিয়ে যাওয়ার চেয়ে খারাপ।


করা উচিত order by nullহবে order by Num2বা আমি বিভ্রান্ত হচ্ছি?
জ্যাক ডগলাস

@ জ্যাক - এটি সদৃশ বর্জনে কোনও পার্থক্য করে না। আপনার ব্যবহারের উপর নির্ভর করে এটি পছন্দসই হতে পারে।
লেইফ রিফেল

দীর্ঘশ্বাস LISTAGG কমা অব্যাহত টম Kyte এরSTRAGG , যা দিয়ে এটি হিসাবে সহজ হিসাবেSTRAGG(DISTINCT ...)
Baodad

অবশেষে এটি সম্ভব: তালিকাগুলির তালিকা
লেড2025

উত্তর:


32

আপনি নিয়মিত ভাব প্রকাশ করতে এবং এর regexp_replaceসাথে সম্মিলনের পরে সদৃশগুলি অপসারণ করতে পারেন listagg:

SELECT Num1, 
       RTRIM(
         REGEXP_REPLACE(
           (listagg(Num2,'-') WITHIN GROUP (ORDER BY Num2) OVER ()), 
           '([^-]*)(-\1)+($|-)', 
           '\1\3'),
         '-') Num2s 
FROM ListAggTest;

এটি আরও পরিশ্রমী হতে পারে যদি ওরাকলসের রেজেেক্স গন্ধটি লুকোহেড বা নন-ক্যাপচারিং গ্রুপগুলিকে সমর্থন করে তবে তা তা নয়

তবে এই সমাধানটি একাধিকবার উত্স স্ক্যান করা এড়ায় না।

এখানে ডিবিফিডাল


নোট করুন যে সদৃশ অপসারণের জন্য এই REGEX_REPLACE কৌশলটির জন্য ডুপ্লিকেট মানগুলি অবশ্যই একত্রিত স্ট্রিংয়ের একে অপরের পাশে থাকতে হবে।
বাওদাদ

2
এটি যা ORDER BY Num2অর্জন করে তা তা নয় ( এখানে দেখুন )। অথবা আপনি কেবল এটি নির্দেশ করার চেষ্টা করছেন যে এটি কাজ করার জন্য আপনার অর্ডার প্রয়োজন?
জ্যাক ডগলাস

13

যতদূর আমি দেখতে পাচ্ছি, বর্তমানে উপলভ্য ভাষার স্পেসিফিকেশন সহ, আপনি যা চান তা অর্জনের জন্য এটি সবচেয়ে সংক্ষিপ্ততম, যদি এটি অবশ্যই করা হয় listagg

select distinct
       a.Num1, 
       b.num2s
  from listaggtest a cross join (
       select listagg(num2d, '-') within group (order by num2d) num2s 
       from (
         select distinct Num2 num2d from listaggtest
       )
      ) b;

আপনার সমাধানটি কাস্টম সমষ্টিগত সমাধানের চেয়েও খারাপ ছিল ?


এটি কাজ করে তবে দুটি পূর্ণ টেবিল স্ক্যান করতে হবে।
লেফ রিফেল

যখন আপনার কাছে একটি ছোট টেবিল রয়েছে যা আপনার সমষ্টি করতে হবে (<100000 সারি) একটি সহজ পুনরুদ্ধারের জন্য পারফরম্যান্স গ্রহণযোগ্যতার চেয়ে বেশি। এটি প্রতিটি সম্ভাব্য উপায় পরীক্ষার প্রায় এক ঘন্টা পরে আমার পছন্দের সমাধান হয়ে উঠেছে!
ম্যাথিউ ডুমুলিন

এটি যখন ডুপ্লিকেটগুলি মধ্যবর্তী মানকে 4000 টির বেশি অক্ষর দেয় তখনও কাজ করে। এটি regexpসমাধানের চেয়ে নিরাপদ করে তোলে ।
গর্ডন লিনফ 21

8

এটি করার জন্য একটি কাস্টম সমষ্টিগত ফাংশন তৈরি করুন ।

ওরাকল ডাটাবেস ম্যাক্স, এমআইএন, এসইউএম এর মতো অনেকগুলি পূর্বনির্ধারিত সমষ্টিগত ফাংশন সরবরাহ করে যা রেকর্ডের একটি সেটে ক্রিয়াকলাপ সম্পাদন করে। এই প্রাক-সংজ্ঞায়িত সামগ্রিক ফাংশনগুলি কেবল স্কেলারের ডেটা দিয়েই ব্যবহার করা যায়। যাইহোক, আপনি এই ফাংশনগুলির নিজস্ব নিজস্ব কাস্টম বাস্তবায়ন তৈরি করতে পারেন বা জটিল ডেটা ব্যবহার করতে সম্পূর্ণ নতুন সামগ্রিক ফাংশনগুলি সংজ্ঞায়িত করতে পারেন example উদাহরণস্বরূপ, বস্তুর ধরণ, অস্বচ্ছ ধরণের এবং এলওবি ব্যবহার করে সঞ্চিত মাল্টিমিডিয়া ডেটা সহ।

ব্যবহারকারী-সংজ্ঞায়িত সামগ্রিক ফাংশনগুলি এসকিউএল ডিএমএল স্টেটমেন্টগুলিতে যেমন ওরাকল ডাটাবেস অন্তর্নির্মিত সমষ্টিগুলির মতো ব্যবহৃত হয়। এই জাতীয় ফাংশনগুলি সার্ভারের সাথে নিবন্ধিত হয়ে গেলে, ডাটাবেসগুলি দেশীয়গুলির পরিবর্তে সরবরাহ করা সমষ্টি রুটিনগুলিকে সহজভাবে আহ্বান করে।

ব্যবহারকারী-সংজ্ঞায়িত সমষ্টিগুলি স্কেলার ডেটার পাশাপাশি ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, আর্থিক বা বৈজ্ঞানিক অ্যাপ্লিকেশনগুলির সাথে যুক্ত জটিল পরিসংখ্যানের ডেটা নিয়ে কাজ করার জন্য বিশেষ একক কার্যকারিতা কার্যকর করা সার্থক হতে পারে।

ব্যবহারকারী-সংজ্ঞায়িত সমষ্টিগুলি এক্সটেনসিবিলিটি ফ্রেমওয়ার্কের একটি বৈশিষ্ট্য। আপনি ওডিসিআইএইগ্রিগ্রেট ইন্টারফেস রুটিন ব্যবহার করে এগুলি প্রয়োগ করেন।


8

যদিও এটি একটি স্বীকৃত উত্তর সহ একটি পুরাতন পোস্ট, আমি মনে করি এলএজি () বিশ্লেষণমূলক ফাংশন এই ক্ষেত্রে ভাল কাজ করে এবং লক্ষণীয়:

  • ল্যাগ () ন্যূনতম ব্যয় সহ নাম্বার কলামের নকল মানগুলি সরিয়ে দেয়
  • ফলাফলগুলি ফিল্টার করার জন্য অ-তুচ্ছ নিয়মিত অভিব্যক্তির দরকার নেই
  • কেবলমাত্র একটি পূর্ণ টেবিল স্ক্যান (সাধারণ উদাহরণ টেবিলের জন্য দাম = 4)

প্রস্তাবিত কোডটি এখানে:

with nums as (
SELECT 
    num1, 
    num2, 
    decode( lag(num2) over (partition by null order by num2), --get last num2, if any
            --if last num2 is same as this num2, then make it null
            num2, null, 
            num2) newnum2
  FROM ListAggTest
) 
select 
  num1, 
  --listagg ignores NULL values, so duplicates are ignored
  listagg( newnum2,'-') WITHIN GROUP (ORDER BY Num2) OVER () num2s
  from nums;

নীচের ফলাফলগুলি ওপি যা চায় তা প্রত্যাশিত:

NUM1  NUM2S       
1   2-3-4-5-6
2   2-3-4-5-6
3   2-3-4-5-6
4   2-3-4-5-6
5   2-3-4-5-6
6   2-3-4-5-6 

7

এখানে আমার সমস্যার সমাধানটি ছিল যা আমার মতে ইতিমধ্যে বিদ্যমান আমাদের কাস্টম সমষ্টিগত ফাংশনটি ব্যবহার করার মতো সুন্দর নয়।

SELECT Num1, listagg(Num2,'-') WITHIN GROUP (ORDER BY NULL) OVER () Num2s FROM (
  SELECT Num1, DECODE(ROW_NUMBER() OVER (PARTITION BY Num2 ORDER BY NULL),
     1,Num2,NULL) Num2 FROM ListAggTest
);

5

পরিবর্তে WMSYS.WM_Concat ব্যবহার করুন।

SELECT Num1, Replace(Wm_Concat(DISTINCT Num2) OVER (), ',', '-')
FROM ListAggTest;

দ্রষ্টব্য: এই ফাংশনটি অননুমোদিত এবং অসমর্থিত। Https://forums.oracle.com/forums/message.jspa?messageID=4372641#4372641 দেখুন ।


6
যদি আপনি ওরাকল সমর্থনকে কল করেন এবং আপনি যদি ব্যবহার করছেন wm_concat(এমনকি যদি আপনি তর্ক করেন wm_concatযে সমস্যাটি নিজেই সৃষ্টি করছে না) তবে তাদের সহায়তা করতে অস্বীকার করার ভিত্তি থাকতে হবে কারণ এটি অনিবন্ধিত এবং অসমর্থিত - যদি আপনি কাস্টম সমষ্টি বা অন্য কোনও ব্যবহার করেন তবে কেস নয় সমর্থিত বৈশিষ্ট্য।
জ্যাক ডগলাস

5

আপনি একটি সংগ্রহ বিবরণ ব্যবহার করতে পারেন এবং তারপরে একটি কাস্টম pl / sQL ফাংশন লিখতে পারেন যা সংগ্রহকে স্ট্রিংয়ে রূপান্তর করে।

CREATE TYPE varchar2_ntt AS TABLE OF VARCHAR2(4000);
CREATE TYPE varchar2_ntt AS TABLE OF VARCHAR2(4000);

select cast(collect(distinct num2 order by num2) as varchar2_ntt) 
from listaggtest

আপনি ব্যবহার করতে পারেন distinctএবং order byএকটি ধারাতেও collectমিলিত থাকলে distinct11.2.0.2 হিসাবে কাজ করবে না :(

ওয়ার্কআরউন্ড একটি সাবলেট হতে পারে:

select collect(num2 order by num2) 
from 
( 
    select distinct num2 
    from listaggtest
)

আমি কাস্টম সমষ্টিগত ফাংশনের চেয়ে কাস্টম প্ল / স্কয়ার ফাংশনটি আরও ভাল হবে তা দেখতে আমি ব্যর্থ। ফলে প্রাপ্ত এসকিউএল অবশ্যই পরবর্তীকালের জন্য সহজ simp যেহেতু এই সমস্যাটি ১১.২.০২.২০১ on এ ছিল সাবলেটলে একটি অতিরিক্ত স্ক্যান যুক্ত করবে যা আমি এড়াতে চাইছিলাম।
লেইফ রিফেল

আমি বলব যে কালেকশনটিকে স্ট্রিংয়ে রূপান্তর করতে ওএনএসইসি নামক একটি পিএল / এসকিউএল ফাংশন হাজারবার বলা সমষ্টিগত ফাংশনের চেয়ে ভাল হতে পারে। আমি মনে করি এটি প্রসঙ্গের সুইচগুলিকে অনেক হ্রাস করবে।
নিকো

আপনার তত্ত্বটি ভাল বলে মনে হচ্ছে এবং কাস্টম সমষ্টিগত ক্রিয়াকলাপটি এড়াতে চেষ্টা করার এক কারণ ছিল এবং লিস্ট্যাগের মতো বিল্ট ইন এগ্রিগ্রেট ফাংশনটি পছন্দ করছিলাম। আপনি যদি কিছু সময়ের তুলনা করতে চান তবে আমি ফলাফলগুলিতে আগ্রহী।
লেইফ রিফেল

2

আমি তালিকাআগের মুখোমুখি হওয়ার আগে এই সমাধানটি তৈরি করেছিলাম, তবে এখনও এই অনুষ্ঠানগুলি যেমন ডুপ্লিকেট মান ইস্যু হিসাবে রয়েছে তবে এই সরঞ্জামটি কার্যকর। ফলাফলগুলিতে আপনাকে নিয়ন্ত্রণ দেওয়ার জন্য নীচের সংস্করণে 4 টি যুক্তি রয়েছে।

ব্যাখ্যা CLOBlist একটি প্যারামিটার হিসাবে কনট্রাক্টর CLOBlistParam নেয়। সিওওলিস্টপ্রামে 4 টি আর্গুমেন্ট রয়েছে

string VARCHAR2(4000) - The variable to be aggregated
delimiter VARCHAR2(100) - The delimiting string
initiator VARCHAR2(100) - An initial string added before the first value only.
no_dup VARCHAR2(1) - A flag. Duplicates are suppressed if this is Y

ব্যবহারের উদাহরণ

--vertical list of comma separated values, no duplicates.
SELECT CLOBlist(CLOBlistParam(column_name,chr(10)||',','','Y')) FROM user_tab_columns
--simple csv
SELECT CLOBlist(CLOBlistParam(table_name,',','','N')) FROM user_tables

জিস্টের লিঙ্কটি নীচে।

https://gist.github.com/peter-genesys/d203bfb3d88d5a5664a86ea6ee34eeca] 1


-- Program  : CLOBlist 
-- Name     : CLOB list 
-- Author   : Peter Burgess
-- Purpose  : CLOB list aggregation function for SQL
-- RETURNS CLOB - to allow for more than 4000 chars to be returned by SQL
-- NEW type CLOBlistParam  - allows for definition of the delimiter, and initiator of sequence
------------------------------------------------------------------
--This is an aggregating function for use in SQL.
--It takes the argument and creates a comma delimited list of each instance.

WHENEVER SQLERROR CONTINUE
DROP TYPE CLOBlistImpl;
WHENEVER SQLERROR EXIT FAILURE ROLLBACK

create or replace type CLOBlistParam as object(
  string    VARCHAR2(4000)
 ,delimiter VARCHAR2(100)  
 ,initiator VARCHAR2(100)  
 ,no_dup    VARCHAR2(1)    )
/
show error

--Creating CLOBlist()
--Implement the type CLOBlistImpl to contain the ODCIAggregate routines.
create or replace type CLOBlistImpl as object
(
  g_list CLOB, -- progressive concatenation
  static function ODCIAggregateInitialize(sctx IN OUT CLOBlistImpl)
    return number,
  member function ODCIAggregateIterate(self  IN OUT CLOBlistImpl
                                     , value IN     CLOBlistParam) return number,
  member function ODCIAggregateTerminate(self        IN  CLOBlistImpl
                                       , returnValue OUT CLOB
                                       , flags       IN  number) return number,
  member function ODCIAggregateMerge(self IN OUT CLOBlistImpl
                                   , ctx2 IN     CLOBlistImpl) return number
)
/
show error


--Implement the type body for CLOBlistImpl.
create or replace type body CLOBlistImpl is
static function ODCIAggregateInitialize(sctx IN OUT CLOBlistImpl)
return number is
begin

  sctx := CLOBlistImpl(TO_CHAR(NULL));
  return ODCIConst.Success;
end;

member function ODCIAggregateIterate(self  IN OUT CLOBlistImpl
                                   , value IN     CLOBlistParam) return number is
begin

   IF self.g_list IS NULL THEN
     self.g_list := value.initiator||value.string;
   ELSIF value.no_dup = 'Y' AND
         value.delimiter||self.g_list||value.delimiter LIKE '%'||value.delimiter||value.string||value.delimiter||'%' 
         THEN
     --Do not include duplicate value    
     NULL;
  ELSE
     self.g_list := self.g_list||value.delimiter||value.string;
   END IF;

  return ODCIConst.Success;
end;

member function ODCIAggregateTerminate(self        IN  CLOBlistImpl
                                     , returnValue OUT CLOB
                                     , flags       IN  number) return number is
begin
  returnValue := self.g_list;
  return ODCIConst.Success;
end;

member function ODCIAggregateMerge(self IN OUT CLOBlistImpl
                                 , ctx2 IN     CLOBlistImpl) return number is
begin

  self.g_list := LTRIM( self.g_list||','||ctx2.g_list,',');

  return ODCIConst.Success;
end;
end;
/
show error

--Using CLOBlist() to create a vertical list of comma separated values

--  SELECT CLOBlist(CLOBlistParam(product_code,chr(10)||',','','Y'))
--  FROM   account


--DROP FUNCTION CLOBlist
--/

PROMPT Create the user-defined aggregate.
CREATE OR REPLACE FUNCTION CLOBlist (input CLOBlistParam) RETURN CLOB
PARALLEL_ENABLE AGGREGATE USING CLOBlistImpl;
/
show error

1

আমি জানি এটি মূল পোস্টের পরে একসময়, তবে গুগলিংয়ের পরে আমি একই সমস্যার উত্তর খুঁজে পেয়েছিলাম এবং ভেবেছিলাম যে অন্য কেউ এখানে এসেছেন তিনি সম্ভবত একটি জটিল উত্তর খুঁজে পেয়ে খুশি হতে পারেন যা অতিরিক্ত জটিল প্রশ্নের উপর নির্ভর করে না বা regexes।

এটি আপনাকে কাঙ্ক্ষিত ফলাফল দেবে:

with nums as (
  select distinct num2 distinct_nums
  from listaggtest
  order by num2
) select num1,
         (select listagg(distinct_nums, '-') within group (order by 1) from nums) nums2list 
         from listaggtest;

1

আমার ধারণাটি হ'ল এইভাবে একটি সঞ্চিত ফাংশন বাস্তবায়ন করা:

CREATE TYPE LISTAGG_DISTINCT_PARAMS AS OBJECT (ELEMENTO VARCHAR2(2000), SEPARATORE VARCHAR2(10));

CREATE TYPE T_LISTA_ELEMENTI AS TABLE OF VARCHAR2(2000);

CREATE TYPE T_LISTAGG_DISTINCT AS OBJECT (

    LISTA_ELEMENTI T_LISTA_ELEMENTI,
        SEPARATORE VARCHAR2(10),

    STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX  IN OUT            T_LISTAGG_DISTINCT) 
                    RETURN NUMBER,

    MEMBER FUNCTION ODCIAGGREGATEITERATE   (SELF  IN OUT            T_LISTAGG_DISTINCT, 
                                            VALUE IN                    LISTAGG_DISTINCT_PARAMS ) 
                    RETURN NUMBER,

    MEMBER FUNCTION ODCIAGGREGATETERMINATE (SELF         IN     T_LISTAGG_DISTINCT,
                                            RETURN_VALUE OUT    VARCHAR2, 
                                            FLAGS        IN     NUMBER      )
                    RETURN NUMBER,

    MEMBER FUNCTION ODCIAGGREGATEMERGE       (SELF               IN OUT T_LISTAGG_DISTINCT,
                                                                                        CTX2                 IN         T_LISTAGG_DISTINCT    )
                    RETURN NUMBER
);

CREATE OR REPLACE TYPE BODY T_LISTAGG_DISTINCT IS 

    STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT T_LISTAGG_DISTINCT) RETURN NUMBER IS 
    BEGIN
                SCTX := T_LISTAGG_DISTINCT(T_LISTA_ELEMENTI() , ',');
        RETURN ODCICONST.SUCCESS;
    END;

    MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT T_LISTAGG_DISTINCT, VALUE IN LISTAGG_DISTINCT_PARAMS) RETURN NUMBER IS
    BEGIN

                IF VALUE.ELEMENTO IS NOT NULL THEN
                        SELF.LISTA_ELEMENTI.EXTEND;
                        SELF.LISTA_ELEMENTI(SELF.LISTA_ELEMENTI.LAST) := TO_CHAR(VALUE.ELEMENTO);
                        SELF.LISTA_ELEMENTI:= SELF.LISTA_ELEMENTI MULTISET UNION DISTINCT SELF.LISTA_ELEMENTI;
                        SELF.SEPARATORE := VALUE.SEPARATORE;
                END IF;
        RETURN ODCICONST.SUCCESS;
    END;

    MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN T_LISTAGG_DISTINCT, RETURN_VALUE OUT VARCHAR2, FLAGS IN NUMBER) RETURN NUMBER IS
      STRINGA_OUTPUT            CLOB:='';
            LISTA_OUTPUT                T_LISTA_ELEMENTI;
            TERMINATORE                 VARCHAR2(3):='...';
            LUNGHEZZA_MAX           NUMBER:=4000;
    BEGIN

                IF SELF.LISTA_ELEMENTI.EXISTS(1) THEN -- se esiste almeno un elemento nella lista

                        -- inizializza una nuova lista di appoggio
                        LISTA_OUTPUT := T_LISTA_ELEMENTI();

                        -- riversamento dei soli elementi in DISTINCT
                        LISTA_OUTPUT := SELF.LISTA_ELEMENTI MULTISET UNION DISTINCT SELF.LISTA_ELEMENTI;

                        -- ordinamento degli elementi
                        SELECT CAST(MULTISET(SELECT * FROM TABLE(LISTA_OUTPUT) ORDER BY 1 ) AS T_LISTA_ELEMENTI ) INTO LISTA_OUTPUT FROM DUAL;

                        -- concatenazione in una stringa                        
                        FOR I IN LISTA_OUTPUT.FIRST .. LISTA_OUTPUT.LAST - 1
                        LOOP
                            STRINGA_OUTPUT := STRINGA_OUTPUT || LISTA_OUTPUT(I) || SELF.SEPARATORE;
                        END LOOP;
                        STRINGA_OUTPUT := STRINGA_OUTPUT || LISTA_OUTPUT(LISTA_OUTPUT.LAST);

                        -- se la stringa supera la dimensione massima impostata, tronca e termina con un terminatore
                        IF LENGTH(STRINGA_OUTPUT) > LUNGHEZZA_MAX THEN
                                    RETURN_VALUE := SUBSTR(STRINGA_OUTPUT, 0, LUNGHEZZA_MAX - LENGTH(TERMINATORE)) || TERMINATORE;
                        ELSE
                                    RETURN_VALUE:=STRINGA_OUTPUT;
                        END IF;

                ELSE -- se non esiste nessun elemento, restituisci NULL

                        RETURN_VALUE := NULL;

                END IF;

        RETURN ODCICONST.SUCCESS;
    END;

    MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT T_LISTAGG_DISTINCT, CTX2 IN T_LISTAGG_DISTINCT) RETURN NUMBER IS
    BEGIN
        RETURN ODCICONST.SUCCESS;
    END;

END; -- fine corpo

CREATE
FUNCTION LISTAGG_DISTINCT (INPUT LISTAGG_DISTINCT_PARAMS) RETURN VARCHAR2
    PARALLEL_ENABLE AGGREGATE USING T_LISTAGG_DISTINCT;

// Example
SELECT LISTAGG_DISTINCT(LISTAGG_DISTINCT_PARAMS(OWNER, ', ')) AS LISTA_OWNER
FROM SYS.ALL_OBJECTS;

আমি দুঃখিত, তবে কিছু ক্ষেত্রে (খুব বড় সেট হিসাবে), ওরাকল এই ত্রুটিটি ফিরিয়ে দিতে পারে:

Object or Collection value was too large. The size of the value
might have exceeded 30k in a SORT context, or the size might be
too big for available memory.

তবে আমি মনে করি এটি শুরু করার একটি ভাল পয়েন্ট;)


নোট করুন যে ওপিতে LISTAGGইতিমধ্যে তাদের নিজস্ব কাস্টম ফাংশন ছিল ; তারা স্পষ্টতই দেখার চেষ্টা করছিল যে LISTAGGসংস্করণ 11.2 হিসাবে উপলব্ধ বিল্ট-ইন ফাংশনটি ব্যবহার করে তারা এটি করার কোনও কার্যকর উপায় খুঁজে পেতে পারে কিনা ।
আরডিফোজ

0

আর একবার চেষ্টা কর:

select num1,listagg(Num2,'-') WITHIN GROUP (ORDER BY NULL) Num2s 
from (
select distinct num1
    ,b.num2
from listaggtest a
    ,(
        select num2
        from listaggtest
    ) b
    order by 1,2
    )
group by num1

অন্যান্য সম্ভাব্য সমাধানগুলির সাথে সমস্যাটি হ'ল কলাম 1 এবং কলাম 2 এর ফলাফলের মধ্যে কোনও সম্পর্ক নেই this এটির চারপাশে কাজ করার জন্য অভ্যন্তরীণ কোয়েরিটি এই সম্পর্কটিকে তৈরি করে এবং তারপরে ফলাফলের সেট থেকে নকলগুলি সরিয়ে দেয়। আপনি তালিকাগুলি করলে ফলাফল সেট ইতিমধ্যে পরিষ্কার is ব্যবহারযোগ্য বিন্যাসে ডেটা পাওয়ার ক্ষেত্রে সমস্যার আরও কিছু করার ছিল।


1
এটি কীভাবে কাজ করে তার কিছু ব্যাখ্যা যোগ করতে চাইতে পারেন।
jkavalik

উত্তরের জন্য ধন্যবাদ এবং সাইটে স্বাগতম। এটি আরও কার্যকর হতে পারে যদি আপনি বর্ণনা করতে পারেন যে এটি কেন কাজ করে এবং এটি কীভাবে সহায়তা করবে।
টম ভি

আমি উত্তরটি আপডেট করার চেষ্টা করেছি তবে এটি ত্রুটিযুক্ত হতে চলেছে। --- অন্যান্য সম্ভাব্য সমাধানগুলির সাথে ইস্যুটি হ'ল কলাম 1 এবং কলাম 2 এর ফলাফলের মধ্যে কোনও সম্পর্ক নেই this এটির চারপাশে কাজ করার জন্য অভ্যন্তরীণ কোয়েরিটি এই সম্পর্কটিকে তৈরি করে এবং তারপরে ফলাফলের সেট থেকে নকলগুলি সরিয়ে দেয়। আপনি তালিকাগুলি করলে ফলাফল সেট ইতিমধ্যে পরিষ্কার is ব্যবহারযোগ্য বিন্যাসে ডেটা পাওয়ার ক্ষেত্রে সমস্যার আরও কিছু করার ছিল।
কেভিন 21

-2

এসকিউএল ইংরেজী খুব কাছাকাছি, সহজ ভাষা হিসাবে ডিজাইন করা হয়েছিল। তাহলে ইংরেজির মতো লেখেন না কেন?

  1. num2 এ সদৃশগুলি মুছে ফেলুন এবং তালিকাবদ্ধভাবে সামগ্রিক ফাংশন হিসাবে ব্যবহার করুন - বিশ্লেষণকারী নয়, স্ট্রিংয়ের উপর কনক্যাট গণনা করতে
  2. একটি ইনপুট জন্য আপনি একটি ফলাফল সারি চান হিসাবে, আসল যোগদান

select num1, num2s
  from (select num2,
               listagg(num2, '-') within group(order by num2) over() num2s
          from listaggtest
         group by num2
       )
  join listaggtest using (num2);


আপনার প্রতিক্রিয়ার জন্য আপনাকে ধন্যবাদ. এই সমাধানের জন্য দুটি পূর্ণ টেবিল স্ক্যান প্রয়োজন, তবে আরও গুরুত্বপূর্ণ এটি সঠিক ফলাফল দেয় না।
লেইফ রিফেল

তার জন্য দুঃখিত, আমি কিছু পুরানো এবং ভুল সংস্করণ পেস্ট করেছি।
fতেফান ওরাভেক

-2
SELECT Num1, listagg(Num2,'-') WITHIN GROUP
(ORDER BY num1) OVER () Num2s FROM 
(select distinct num1 from listAggTest) a,
(select distinct num2 from ListAggTest) b
where num1=num2(+);

এটি প্রদত্ত তথ্যের জন্য সঠিক ফলাফলগুলি দেয়, তবে এটির একটি ভুল ধারণা রয়েছে। Num1 এবং Num2 সম্পর্কিত নয়। Num1 একই সাথে Char1 হতে পারে মানগুলি a, e, i, o, u, y সমেত। নিখরচায়, এই সমাধানটির জন্য টেবিলের দুটি সম্পূর্ণ স্ক্যান প্রয়োজন সামগ্রিক ফাংশনটি ব্যবহারের পুরো উদ্দেশ্যকে পরাস্ত করে। যদি সমাধানটিতে দুটি টেবিল স্ক্যানের অনুমতি দেওয়া হয়, তবে এটিকে অগ্রাধিকার দেওয়া হবে (স্যাম্পল ডেটার সাথে এটি অন্য যে কোনও কিছুর চেয়ে কম খরচ করে)। SELECT Num1, ( SELECT LISTAGG(Num2) WITHIN GROUP (ORDER BY Num2) FROM (SELECT distinct Num2 FROM listAggTest) ) Num2 FROM ListAggTest;
লেইফ রিফেল

-2

সবচেয়ে কার্যকর সমাধান হ'ল গ্রুপ দ্বারা অভ্যন্তরীণ নির্বাচন করুন, কারণ DISTINCT এবং নিয়মিত প্রকাশগুলি নরকের মতো ধীর।

SELECT num1, LISTAGG(num2, '-') WITHIN GROUP (ORDER BY num2) AS num2s
    FROM (SELECT num1, num2
              FROM ListAggTest
              GROUP BY num1, num2)
    GROUP BY num1;

এই সমাধানটি বেশ সহজ - প্রথমে আপনি num1 এবং num2 (অভ্যন্তরীণ নির্বাচন) এর সমস্ত অনন্য সংমিশ্রণ পান এবং তারপরে আপনি num1 দ্বারা বিভাজনযুক্ত সমস্ত num2 এর স্ট্রিং পাবেন।


এই ক্যোয়ারী অনুরোধিত ফলাফলগুলি ফেরত দেয় না। এটি একই ফলাফল প্রদান করে SELECT * FROM ListAggTest;
লেফ রিফেল

তার প্রতিরক্ষার জন্য, সম্ভবত অন্য একটি স্ট্যাকওভারফ্লো সমস্যা থেকে এই সমাধানটির দিকে তাকে ডুপ্লিকেট চিহ্নিত করা হয়েছিল যা এই সমাধানটি সমাধান করেএটাই আমি সমাধান চাইছিলাম। দেখে মনে হচ্ছে আমার নিজের পোস্ট গ্রহণের জন্য আমার বিভিন্ন ধারণা তৈরি করতে হবে এবং তাই আমি এই মন্তব্যটি দিয়ে এই প্রশ্নটি একা রেখে দেব।
জেরার্ড ওনিল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.