2016-04-08 10 views
0

karmaşık bir sorguda yardıma ihtiyacınız var.Oracle XE, bir sütuna göre farklı satır kombinasyonlarını saymak ve görüntülemek

USERID SERVICE 
1   A 
1   B 
2   A 
3   A 
3   B 
4   A 
4   C 
5   A 
6   A 
7   A 
7   B 

Tamam, dönmek ve SERVİS sütuna dayalı kendi sayımları ile benim tabloda mevcut tüm olası kombinasyonları görüntülemek için sorguyu istiyorum: Bu benim tablosundan bir özdür. Örneğin, ilk kullanıcı A ve B servisine sahiptir, bu bir kez gerçekleşen bir kombinasyondur. Bir sonraki kullanıcı sadece A servisine sahip, bu bir kez daha meydana gelen bir kombinasyon. Üçüncü kullanıcı servis A ve B, bu kez gerçekleştiği ve bu özel girişe göre benim çıkış böyle bir tablo olurdu Yani bu kombinasyon için sayım, şimdi vb 2'dir:

A AB AC ABC B BC 
3 3 1 0 0 0 

Yani netleştirmek için biraz daha fazla, eğer 3 hizmet varsa, o zaman 3 var! olası kombinasyonlar; 3x2x1 = 6 ve bunlar A, B, C, AB, AC, BC ve ABC'dir. Ve tablomda, kendilerine atanan bu hizmet kombinasyonuna sahip kullanıcı sayısı bulunmalıdır.

bu sorguyu kullanarak bir matris oluşturmak ve sonra da CUBE fonksiyonunu kullanarak tüm sayımları elde denedi:

select service_A, service_B, service_C from 
    (select USERID, 
    max(case when SERVICE =A then 1 else null end) service_A, 
    max(case when SERVICE =B then 1 else null end) service_B, 
    max(case when SERVICE =C then 1 else null end) service_C 
    from SOME_TABLE) 
group by CUBE(service_A, service_B,service_C); 

Ama tüm kombinasyonların sayısını alamadım. Sadece olan kombinasyonlara ihtiyacım var, bu yüzden 0 saymak gerekli değil, ancak bunları görüntülemek tamam. Teşekkürler.

+0

size olası kombinasyonların bir dizi var dinamik sütunlar için

SERVICE NUM_USERS ------- ---------- AC 1 A 3 AB 3 

PL/SQL? Yani, sorgunuz kaç tane sütun döndürecek? Değilse, bunu basit bir sorguyla yapamazsınız, ancak dinamik bir şeye ihtiyacınız vardır (ve sonra bilinmeyen sayıda sütun ile sonuç kümesini işlemek zor olabilir) – Aleksej

+0

Hangi servislerin mevcut olduğunu biliyorum, örneğin 10 Bir kişinin sahip olabileceği hizmetler. Yani hesaplama yapmak ve 10 tane olduğunu bulmak mümkün! Çok sayıda olan farklı hizmet kombinasyonlarının sayısı. Yani bu maksimum sütun sayısı olurdu. Ama çoğu sayım 0 olacak, sorun hangileri olduğunu bilmem, dolayısıyla hepsini hesaplamam gerekiyor. – Hrvoje85

cevap

2

Dinamik sütunlar olarak kullanmayın (PL/SQL ve dinamik SQL kullanmadan yapmak zordur) ancak bunun yerine satırlar olarak çıktılar (eğer bir ön uçunuz varsa, genellikle satırları sütunlara çevirebilir) kolay) oracle can daha:

Oracle Kurulumu:

CREATE TABLE some_table (USERID, SERVICE) AS 
SELECT 1, 'A' FROM DUAL UNION ALL 
SELECT 1, 'B' FROM DUAL UNION ALL 
SELECT 2, 'A' FROM DUAL UNION ALL 
SELECT 3, 'A' FROM DUAL UNION ALL 
SELECT 3, 'B' FROM DUAL UNION ALL 
SELECT 4, 'A' FROM DUAL UNION ALL 
SELECT 4, 'C' FROM DUAL UNION ALL 
SELECT 5, 'A' FROM DUAL UNION ALL 
SELECT 6, 'A' FROM DUAL UNION ALL 
SELECT 7, 'A' FROM DUAL UNION ALL 
SELECT 7, 'B' FROM DUAL; 

Sorgu:

SELECT service, 
     COUNT(userid) AS num_users 
FROM (
    SELECT userid, 
     LISTAGG(service) WITHIN GROUP (ORDER BY service) AS service 
    FROM some_table 
    GROUP BY userid 
) 
GROUP BY service; 

Çıktı:

VARIABLE cur REFCURSOR; 

DECLARE 
    TYPE string_table IS TABLE OF VARCHAR2(4000); 
    TYPE int_table IS TABLE OF INT; 
    t_services string_table; 
    t_counts int_table; 
    p_sql  CLOB; 
BEGIN 
    SELECT service, 
     COUNT(userid) AS num_users 
    BULK COLLECT INTO t_services, t_counts 
    FROM (
    SELECT userid, 
      CAST(LISTAGG(service) WITHIN GROUP (ORDER BY service) AS VARCHAR2(2)) AS service 
    FROM some_table 
    GROUP BY userid 
) 
    GROUP BY service; 

    p_sql := EMPTY_CLOB() || 'SELECT '; 
    p_sql := p_sql || t_counts(1) || ' AS "' || t_services(1) || '"'; 
    FOR i IN 2 .. t_services.COUNT LOOP 
    p_sql := p_sql || ', ' || t_counts(i) || ' AS "' || t_services(i) || '"'; 
    END LOOP; 
    p_sql := p_sql || ' FROM DUAL'; 

    OPEN :cur FOR p_sql; 
END; 
/

PRINT cur; 

Çıktı:

AC A AB 
--- --- --- 
1 3 3 
+0

Vay, hızlı ve doğru cevap için teşekkürler, bu tam olarak istediğim şey! – Hrvoje85

İlgili konular