用listagg选择不同的值

问题描述 投票:0回答:1

我使用oracle 12c数据库。我试图使用子查询方法用listagg选择不同的值。但是我得到了一个错误 "ORA-01427:单行子查询返回多于一行01427。00000 - "single-row subquery returns more than one row""单行子查询返回多于一行"。

这是我的代码。

SELECT DISTINCT nr.sd_id,
            ( select listagg(nr.r_num,' ') within group (ORDER BY Nlssort(nr.r_num, 'NLS_SORT=BINARY_CI'))
                  OVER ( PARTITION BY nr.sd_id, nr.rid, nr.rr_id) r_num_group 
                  from (select distinct r_num from sg_nr) )
FROM   sg_nr nr;
sql oracle plsql distinct listagg
1个回答
0
投票

请使用下面的查询。

SELECT DISTINCT nr.sd_id, listagg(nr.r_num,' ') within group (ORDER BY 
Nlssort(nr.r_num, 'NLS_SORT=BINARY_CI')
OVER ( PARTITION BY nr.sd_id, nr.rid, nr.rr_id) r_num_group FROM  sg_nr nr;

0
投票

你不需要一个windows子句(OVER)。只要用 WHERE 子句在内部子查询内,如下所示。

SELECT DISTINCT NR.SD_ID,
                ( SELECT LISTAGG(NR.R_NUM,' ') WITHIN GROUP(
                         ORDER BY NLSSORT( NR.R_NUM, 'NLS_SORT=BINARY_CI')) 
                      FROM (
                        SELECT DISTINCT R_NUM
                          FROM SG_NR NRIN
                         WHERE NRIN.SD_ID = NR.SD_ID
                           AND NRIN.RID = NR.RID
                           AND NRIN.RR_ID = NR.RR_ID)) AS R_NUM_GROUP
  FROM SG_NR NR;

最好的方法是使用子查询作为内部视图,并将其与主表连接,如下所示。

SELECT NR.SD_ID, NRIN.R_NUM_GROUP
  FROM SG_NR NR
  JOIN (
    SELECT NRIN.SD_ID, NRIN.RID, NRIN.RR_ID,
           LISTAGG(NRIN.R_NUM, ' ') WITHIN GROUP(
                ORDER BY NLSSORT( NRIN.R_NUM, 'NLS_SORT=BINARY_CI' )
           ) R_NUM_GROUP
      FROM ( SELECT DISTINCT NRIN.R_NUM, NRIN.SD_ID, NRIN.RID, NRIN.RR_ID
               FROM SG_NR NRIN) NRIN
      GROUP BY NRIN.SD_ID, NRIN.RID, NRIN.RR_ID
    ) NRIN ON NRIN.SD_ID = NR.SD_ID
          AND NRIN.RID = NR.RID
          AND NRIN.RR_ID = NR.RR_ID;

0
投票

从性能的角度来看,可以这样做,因为你已经在使用同一个表。SG_NR. 然后使用 LISTAGG 功能与 材料化 提示:

WITH NR AS (SELECT /*+MATERIALIZE*/
                  * FROM SG_NR)
SELECT NR.SD_ID, NR2.R_NUM_GROUP
  FROM NR
       INNER JOIN
       (  SELECT NR2.SD_ID,
                 NR2.RID,
                 NR2.RR_ID,
                 LISTAGG (
                    NR2.R_NUM,
                    ' ')
                 WITHIN GROUP (ORDER BY
                                  NLSSORT (NR2.R_NUM, 'NLS_SORT=BINARY_CI'))
                    R_NUM_GROUP
            FROM (  SELECT NR2.R_NUM,
                           NR2.SD_ID,
                           NR2.RID,
                           NR2.RR_ID
                      FROM NR NR2
                  GROUP BY NR2.R_NUM,
                           NR2.SD_ID,
                           NR2.RID,
                           NR2.RR_ID) NR2
        GROUP BY NR2.SD_ID, NR2.RID, NR2.RR_ID) NR2
          ON     NR2.SD_ID = NR.SD_ID
             AND NR2.RID = NR.RID
             AND NR2.RR_ID = NR.RR_ID
© www.soinside.com 2019 - 2024. All rights reserved.