ListAgg’deki çiftleri ortadan kaldırın (Oracle)


44

Oracle 11.2'den önce bir sütunu bir satırda birleştirmek için özel bir toplama işlevi kullanıyordum. 11.2 LISTAGGİşlev eklendi , bu yüzden onu kullanmaya çalışıyorum. Benim sorunum sonuçlardaki kopyaları elimine etmem gerektiği ve bunu yapamayacağım gibi görünüyor.

İşte bir örnek.

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

Görmek istediğim şudur:

      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

İşte listaggyakın, ancak yinelenenleri yok etmeyen bir sürüm.

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

Bir çözümüm var, ancak özel toplama işlevini kullanmaya devam etmekten daha kötü.


Meli order by nullolmak order by Num2ya da ben bocalama ben?
Jack Douglas

@Jack - Yinelenen elemede bir fark yaratmaz. Kullanımınıza bağlı olarak, bu arzu edilebilir.
Leigh Riffel

LISTAGGSTRAGGSTRAGG(DISTINCT ...)
çekişmesi

Sonunda mümkün: LISTAGG DISTINCT
lad2025

Yanıtlar:


32

Düzenli ifadeler kullanabilir ve regexp_replaceçoğaltmaları birleştirme işleminden sonra kaldırabilirsiniz listagg:

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

Oracle'ın regex lezzet bakışı destekli veya yakalayıcı olmayan gruplar destekliyorsa, bu daha düzenli olabilir, ancak öyle değil .

Ancak bu çözüm kaynağı bir kereden fazla taramaktan kaçınır.

DBFiddle burada


Bu REGEX_REPLACE tekniğinin yinelemeleri kaldırmak için çalışması için, yinelenen değerlerin toplanmış dizede yan yana olması gerektiğini unutmayın.
Baodad

2
Bunu sağlayan ORDER BY Num2şey değil mi ( buraya bakın ). Yoksa sadece çalışması için SİPARİŞ BY SİPARASI ihtiyacınız olduğunu işaret etmeye mi çalışıyorsunuz?
Jack Douglas

13

Bildiğim kadarıyla gördüğünüz gibi, mevcut dil şartname ile, bu ne istediğinizi elde etmek için en kısa olduğu takdirde onunla yapılmalıdır 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;

Özel toplu çözümden daha kötü olan çözümünüz neydi?


Bu çalışır, ancak iki tam masa taraması yapmak zorundadır.
Leigh Riffel

Toplamanız gereken küçük bir tablonuz varsa (<100000 satır), performans basit bir alım için kabul edilebilirden daha fazladır. Bu, olası her yolu test etmek için neredeyse bir saatlik testten sonra benim seçim çözümümdü!
Mathieu Dumoulin

Bu aynı zamanda, kopyaların ara değeri 4000 karakterin üzerine getireceği zaman da işe yarar. Bu regexpçözümden daha güvenli hale getirir .
Gordon Linoff 16:15

8

Bunu yapmak için özel bir toplama işlevi oluşturun .

Oracle veritabanı, bir dizi kayıt üzerinde işlem yapmak için MAX, MIN, SUM gibi bir dizi önceden tanımlanmış toplama işlevi sağlar. Bu önceden tanımlanmış toplama işlevleri yalnızca skaler verilerle kullanılabilir. Bununla birlikte, bu işlevler için kendi özel uygulamalarınızı oluşturabilir veya karmaşık verilerle, örneğin nesne türleri, opak türleri ve LOB'ler kullanılarak depolanan multimedya verileriyle kullanmak için tamamen yeni toplama işlevleri tanımlayabilirsiniz.

Kullanıcı tanımlı toplama işlevleri, Oracle veritabanı yerleşik toplamalarında olduğu gibi SQL DML deyimlerinde kullanılır. Bu tür işlevler sunucuya kaydedildikten sonra, veritabanı yalnızca yerel olanları yerine sağladığınız toplama yordamlarını çağırır.

Kullanıcı tanımlı agregalar, skaler verilerle de kullanılabilir. Örneğin, finansal veya bilimsel uygulamalarla ilgili karmaşık istatistiksel verilerle çalışmak için özel toplu fonksiyonlar uygulamak faydalı olabilir.

Kullanıcı tanımlı toplamlar, Genişletilebilirlik Çerçevesinin bir özelliğidir. ODCIAggregate arabirim yordamlarını kullanarak uygularsınız.


8

Bu kabul edilmiş bir cevabı olan eski bir yazı olmasına rağmen, LAG () analitik fonksiyonunun bu durumda iyi çalıştığını ve dikkat çekici olduğunu düşünüyorum:

  • LAG (), minimum masrafla num2 sütununda yinelenen değerleri kaldırır
  • Sonuçları filtrelemek için önemsiz olmayan normal ifadelere gerek yok
  • Yalnızca bir tam tablo taraması (basit örnek tabloda maliyet = 4)

İşte önerilen kod:

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;

Aşağıdaki sonuçlar OP'nin istediği gibi görünüyor:

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

İşte bence zaten var olan özel toplama fonksiyonumuzu kullanmak kadar hoş olmayan bir soruna çözümüm.

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

Bunun yerine WMSYS.WM_Concat kullanın.

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

Not: Bu işlev belgelenmemiş ve desteklenmemektedir. Bakınız https://forums.oracle.com/forums/message.jspa?messageID=4372641#4372641 .


6
Oracle desteğini ararsanız ve kullanıyorsanız wm_concat( wm_concatsoruna neden olmadığını iddia etseniz bile ) yardım almayı reddetme gerekçeleri var çünkü belgelenmemiş ve desteklenmiyor - özel bir toplama veya başka bir şey kullanmanız durumunda Desteklenen özellik
Jack Douglas

5

Ayrıca collect deyimini kullanabilir ve ardından koleksiyonu bir dizeye dönüştüren özel bir pl / sql işlevi yazabilirsiniz.

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

Sen distinctve yan tümce kullanabilirsiniz order by, collectancak birleşik eğer distinct11.2.0.2 itibariyle işe yaramaz

Geçici çözüm bir alt seçim olabilir:

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

Özel bir pl / sql işlevinin özel bir toplama işlevinden daha iyi olacağını göremiyorum. Sonuçta ortaya çıkan SQL, ikincisi için kesinlikle daha kolaydır. Bu sorun 11.2.0.2'de olduğundan alt seçim, kaçınmaya çalıştığım ek bir tarama eklerdi.
Leigh Riffel

Koleksiyonu bir dizgeye dönüştürmek için ONCE adlı bir PL / SQL işlevinin binlerce kez denilen toplam işlevden daha iyi olabileceğini söyleyebilirim. Bunun bağlam anahtarlarını çok azaltacağını düşünüyorum.
Nico

Teoriniz kulağa hoş geliyor ve özel toplama işlevinden kaçınmaya çalışmamın bir nedeni vardı ve LISTAGG gibi yerleşik bir toplama işlevini tercih ediyordum. Bazı zamanlama karşılaştırmaları yapmak istiyorsanız sonuçlarla ilgilenirim.
Leigh Riffel

2

ListAgg ile karşılaşmadan önce bu çözümü yarattım, fakat bu yinelenen değer sorunu gibi durumlar hala var, sonra bu araç kullanışlıdır. Aşağıdaki sürüm size sonuçlar üzerinde kontrol vermenizi sağlayacak 4 argümana sahiptir.

Açıklama CLOBlist, CLOBlistParam'ı yapılandırıcı olarak parametre olarak alır. CLOBlistParam 4 argüman içeriyor

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

Örnek kullanım

--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

Gist bağlantısı aşağıda.

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

Orijinal gönderiden bir süre sonra olduğunu biliyorum, ancak bu Googling’den sonra aynı soruyu cevaplamak için bulduğum ilk yerdi ve buraya gelen bir başkasının aşırı karmaşık sorgulara dayanmayan kısa ve özlü bir cevap bulmaktan mutlu olacağını düşündüm. veya regexes.

Bu size istenen sonucu verecektir:

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

Benim fikrim şunun gibi saklanmış bir işlevi uygulamaktır:

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;

Üzgünüm, ama bazı durumlarda (çok büyük bir set için), Oracle bu hatayı verebilir:

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.

ama bunun iyi bir başlangıç ​​noktası olduğunu düşünüyorum;)


OP'nin LISTAGGzaten kendi özel işlevi olduğunu unutmayın ; açıkça LISTAGG11.2 sürümünden itibaren mevcut olan yerleşik işlevi kullanarak bunu yapmanın etkili bir yolunu bulabileceklerini görmeye çalışıyorlardı .
RDFozz

0

Bunu dene:

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

Diğer olası çözümlerle ilgili sorun, sütun 1 ve sütun 2 sonuçları arasında bir korelasyon olmamasıdır. Bu soruna geçici bir çözüm bulmak için, iç korelasyon bu korelasyonu yaratır ve sonra kopyaları bu sonuç kümesinden kaldırır. Listagg yaptığınızda, sonuç kümesi zaten temiz. Bu sorunun verileri kullanışlı bir biçimde almasıyla ilgisi vardı.


1
Nasıl çalıştığı hakkında bir açıklama eklemek isteyebilirsiniz.
jkavalik

Cevabınız için teşekkürler ve sitemize hoş geldiniz. Bunun neden işe yaradığını ve nasıl yardım edeceğini açıklayabilirseniz daha da faydalı olabilir.
Tom V,

Cevabı güncellemeye çalışıyorum ancak hata devam ediyor. --- Diğer olası çözümlerle ilgili sorun, sütun 1 ve sütun 2 sonuçları arasında bir korelasyon bulunmamasıdır. Bu soruna geçici bir çözüm bulmak için bu korelasyonu oluşturur ve kopyaları bu sonuç kümesinden kaldırır. Listagg yaptığınızda, sonuç kümesi zaten temiz. Bu sorunun verileri kullanışlı bir biçimde almasıyla ilgisi vardı.
Kevin,

-2

SQL, ingilizceye çok yakın, basit bir dil olarak tasarlanmıştır. Peki neden İngilizce olarak yazmıyorsun?

  1. num2'deki kopyaları elimine et ve listagg'i toplama işlevi olarak kullan - analitik değil, string üzerinde concat hesaplamak için
  2. bir giriş için bir sonuç satırı istediğiniz gibi orijinale katılın

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


Cevabınız için teşekkürler. Bu çözüm iki tam masa taraması gerektirir, ancak daha da önemlisi doğru sonuçları vermez.
Leigh Riffel 10'11

Bunun için üzgünüm, bazı eski ve yanlış sürümleri yapıştırdım.
Štefan Oravec

-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(+);

Bu, verilen veriler için doğru sonuçları verir, ancak yanlış bir varsayıma sahiptir. Num1 ve Num2 ilgisizdir. Num1, a, e, i, o, u, y değerlerini içeren Char1 de olabilir. Her şeye rağmen, bu çözüm toplam işlevini kullanma amacını ortadan kaldıran tablonun iki tam taramasını gerektirir. Çözelti iki masa taramasına izin verirse, bu tercih edilir (örnek verilerle her şeyden daha düşük bir maliyeti vardır). SELECT Num1, ( SELECT LISTAGG(Num2) WITHIN GROUP (ORDER BY Num2) FROM (SELECT distinct Num2 FROM listAggTest) ) Num2 FROM ListAggTest;
Leigh Riffel

-2

En etkili çözüm, DISTINCT ve normal ifadelerin cehennem kadar yavaş olması nedeniyle GROUP BY ile içsel SELECT'tir.

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

Bu çözüm oldukça basittir - önce num1 ve num2'nin tüm benzersiz kombinasyonlarını (içsel SELECT) alırsınız ve sonra num1 tarafından gruplandırılmış tüm num2 dizelerini elde edersiniz.


Bu sorgu istenen sonuçları getirmiyor. İle aynı sonuçları verir SELECT * FROM ListAggTest;.
Leigh Riffel

Savunmasında, muhtemelen bu çözüm olduğunu yinelenen işaretli başka stackoverflow problemden bu çözümün işaret edildi yapar düzeltme. O 'Ben istediğim çözüm bu. Benim kendi görüşümü yayınlamak için farklı varsayımlar yapmam gerekiyor gibi görünüyor, bu yüzden bu soruyu bu yorumla yalnız bırakacağım.
Gerard ONeill
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.