Oracle - 唯一的Listagg值

时间:2016-02-09 17:51:15

标签: sql oracle oracle10g listagg

我是使用Listagg的新手。以下脚本的工作原理为我提供了一个值列表,但列表重复了这些值。

是否可以使用Listagg仅返回唯一的值列表。

我正在使用oracle 10g。

select distinct ds.catnr,ds.planqty, ds.ordnr, ds.posnr, ds.segnr, 
listagg(case when not li.paco is null then (select unique max(li1.paco) from leos_item li1 where li.av_part_no = li1.av_part_no) end, ', ') within group (order by pd.part_no) inq_no
from oes_delsegview ds, oes_address ad, oes_opos op, oes_nrbom nr, scm_prodtyp sp, leos_item li, part_description pd
where ds.delnr = ad.key
and ad.adr = ds.deladr
and ds.pos_o_status not in ('9', 'D')
and ds.pos_c_status not in ('9', 'D')
and ds.seg_o_status not in ('9', 'D')
and ds.seg_c_status not in ('9', 'D')
and ds.cunr in ('W31170','W31172')
and ds.pos_type != 'RC'
and ds.ordnr = op.ordnr
and ds.posnr = op.posnr
and ds.catnr = pd.catnr
and ds.prodtyp = pd.prodtyp
and ds.packtyp = pd.packtyp
and ds.catnr = nr.p_catnr (+)
and ds.prodtyp = nr.p_prodtyp (+)
and ds.packtyp = nr.p_packtyp (+)
and nr.c_prodtyp = sp.prodtyp (+) 
and sp.prodgrp (+) = 'COMP'
and substr(nr.c_prodtyp,1,2) not in ('MT','LF')
and nr.c_catnr = li.catnr (+)
and nr.c_prodtyp = li.prodtyp (+)
and nr.c_packtyp = li.packtyp (+)
and pd.catnr = '9780007938797'
group by ds.catnr,ds.planqty, ds.ordnr, ds.posnr, ds.segnr

我的Listagg的结果是:

14/061127-12, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16, 14/061127-16

我希望看到的是:

14/061127-12, 14/061127-16

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:2)

我删除了您distinct个查询中已有group by个字段后的第一个Select,并将case when替换为select个查询:

select ds.catnr,ds.planqty, ds.ordnr, ds.posnr, ds.segnr, 
    listagg((select distinct max(li1.paco) from leos_item li1 where li.av_part_no = li1.av_part_no and li.paco is not null), ', ') within group (order by pd.part_no) inq_no
    from oes_delsegview ds, oes_address ad, oes_opos op, oes_nrbom nr, scm_prodtyp sp, leos_item li, part_description pd
    where ds.delnr = ad.key
    and ad.adr = ds.deladr
    and ds.pos_o_status not in ('9', 'D')
    and ds.pos_c_status not in ('9', 'D')
    and ds.seg_o_status not in ('9', 'D')
    and ds.seg_c_status not in ('9', 'D')
    and ds.cunr in ('W31170','W31172')
    and ds.pos_type != 'RC'
    and ds.ordnr = op.ordnr
    and ds.posnr = op.posnr
    and ds.catnr = pd.catnr
    and ds.prodtyp = pd.prodtyp
    and ds.packtyp = pd.packtyp
    and ds.catnr = nr.p_catnr (+)
    and ds.prodtyp = nr.p_prodtyp (+)
    and ds.packtyp = nr.p_packtyp (+)
    and nr.c_prodtyp = sp.prodtyp (+) 
    and sp.prodgrp (+) = 'COMP'
    and substr(nr.c_prodtyp,1,2) not in ('MT','LF')
    and nr.c_catnr = li.catnr (+)
    and nr.c_prodtyp = li.prodtyp (+)
    and nr.c_packtyp = li.packtyp (+)
    and pd.catnr = '9780007938797'
    group by ds.catnr,ds.planqty, ds.ordnr, ds.posnr, ds.segnr

答案 1 :(得分:0)

我使用regexp_replace函数删除listagg中的重复项;

regexp_replace(
    listagg((select distinct max(li1.paco) from leos_item li1 where li.av_part_no = li1.av_part_no and li.paco is not null), ', ') within group (order by pd.part_no) 
    ,'([^,]+)(,\1)+', '\1') inq_no

似乎工作正常。

LISTAGG in oracle to return distinct values

答案 2 :(得分:0)

您可以通过RegEx替换来完成。这是一个例子:

-- Citations Per Year - Cited Publications main query. Includes list of unique associated core project numbers, ordered by core project number.
SELECT ptc.pmid AS pmid, ptc.pmc_id, ptc.pub_title AS pubtitle, ptc.author_list AS authorlist,
  ptc.pub_date AS pubdate,
  REGEXP_REPLACE( LISTAGG ( ppcc.admin_phs_org_code || 
    TO_CHAR(ppcc.serial_num,'FM000000'), ',') WITHIN GROUP (ORDER BY ppcc.admin_phs_org_code || 
    TO_CHAR(ppcc.serial_num,'FM000000')),
    '(^|,)(.+)(,\2)+', '\1\2')
  AS projectNum
FROM publication_total_citations ptc
  JOIN proj_paper_citation_counts ppcc
    ON ptc.pmid = ppcc.pmid
   AND ppcc.citation_year = 2013
  JOIN user_appls ua
    ON ppcc.admin_phs_org_code = ua.admin_phs_org_code
   AND ppcc.serial_num = ua.serial_num
   AND ua.login_id = 'EVANSF'
GROUP BY ptc.pmid, ptc.pmc_id, ptc.pub_title, ptc.author_list, ptc.pub_date
ORDER BY pmid;

答案 3 :(得分:0)

超级简单的答案解决了

applyMeanSD <- function(y, mean_target, sd_target, max_iter = 10){
    iter <- 0
    while(any(y < 0) || iter < max_iter){
        iter <- iter + 1
        y <- y[y > 0] #throws away all outliers
        if (length(y) > 1)
            y <- mean_target + (y - mean(y)) * sd_target/sd(y)
        else 
            return (NULL)
    }
    return(y)
}

test2 <- applyMeanSD(test <- rnorm(100, 0, 1), 1, 0.5)
test #negative values included
test2 #no negative values
mean(test2)
sd(test2)

- &GT;

14 / 061127-12,14 / 061127-16

请参阅我的完整答案here