【问题标题】:(Oracle)Splitting strings then averaging at once(Oracle)拆分字符串然后一次平均
【发布时间】:2020-05-13 09:16:05
【问题描述】:

我的列 COL1 有时会有诸如“10|20”之类的数据。 如果数据有“|”,我的目标是拆分数据。然后将它们平均得到 15。 如何修改下面的代码以添加这样的 COL2?

(Expected results)

COL1      COL2
-------  -------
10        10
10|20     15
10|20|30  20

(My code)
WITH A AS (
SELECT '10' COL1 FROM DUAL
UNION ALL
SELECT '10|20' FROM DUAL
UNION ALL
SELECT '10|20|30' FROM DUAL
) SELECT COL1 FROM A  DUAL 

【问题讨论】:

    标签: sql oracle average


    【解决方案1】:

    您可以使用相关的XMLTABLE 来拆分值:

    WITH A AS (
    SELECT '10' COL1 FROM DUAL UNION ALL
    SELECT '10|20' FROM DUAL UNION ALL
    SELECT '10|20|30' FROM DUAL
    )
    SELECT col1,
           (
             SELECT AVG( TO_NUMBER( column_value ) )
             FROM   xmltable(('"' || REPLACE(a.col1, '|', '","') || '"'))
           ) AS col2
    FROM   A
    

    哪些输出:

    COL1 | COL2 :------- | ---: 10 | 10 10|20 | 15 10|20|30 | 20

    db小提琴here

    【讨论】:

      【解决方案2】:

      给你:

      SQL> with a as
        2    (select '10' col1  from dual union all
        3     select '10|20'    from dual union all
        4     select '10|20|30' from dual
        5    )
        6  select
        7    col1,
        8    avg(to_number(regexp_substr(col1, '[^\|]+', 1, column_value))) col2
        9  from a cross join
       10    table(cast(multiset(select level from dual
       11                        connect by level <= regexp_count(col1, '\|') + 1
       12                       ) as sys.odcinumberlist))
       13  group by col1
       14  order by col1;
      
      COL1           COL2
      -------- ----------
      10               10
      10|20            15
      10|20|30         20
      
      SQL>
      

      它有什么作用?

      第 8 行(在第 10 - 12 行的帮助下):

      • REGEXP_SUBSTR 部分用于将列拆分为行
      • TO_NUMBER 将子字符串转换为数字
      • AVG 计算平均值

      【讨论】:

        【解决方案3】:
        WITH t AS (
        SELECT '10' text FROM DUAL
        UNION ALL
        SELECT '10|20' FROM DUAL
        UNION ALL
        SELECT '10|20|30' FROM DUAL
        ) 
        SELECT  text,
                avg(to_number(regexp_substr(t.text, '[^\|]+', 1, column_value))) average
            FROM t,
              TABLE (CAST (MULTISET
              (SELECT LEVEL FROM dual
                      CONNECT BY instr(t.text, '|', 1, LEVEL - 1) > 0
              ) AS sys.odciNumberList ) ) lines
        GROUP BY t.text ORDER BY t.text;
        
        TEXT        AVERAGE
        -------- ----------
        10               10
        10|20            15
        10|20|30         20
        

        【讨论】:

          猜你喜欢
          • 2019-01-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-15
          • 1970-01-01
          • 1970-01-01
          • 2022-11-17
          • 1970-01-01
          相关资源
          最近更新 更多