LISTAGG相当于10g

时间:2018-05-21 09:28:35

标签: sql oracle10g string-aggregation

我使用的是Oracle 10g,所以不幸的是我无法使用listagg(因为这需要11g)。

所以我想将下面的代码移植到10g的替代品中:

select count(*) from (
    select listagg(flag) within group (order by dt) as flags
    from   temp_output_ovlp
)
where not regexp_like(flags, 'HH|EE|HS|SE');

这将针对以下内容在HH|EE|HS|SE内搜索匹配的EHEEESHEHH模式:

|----------|----------|
|  DT      |  FLAG    |
|----------|----------|
|  10      |  E       |
|  20      |  H       |
|  30      |  E       |
|  40      |  E       |
|  50      |  E       |
|  60      |  S       |
|  70      |  H       |
|  75      |  E       |
|  80      |  H       |
|  100     |  H       |
|----------|----------|

demo

我按照建议here尝试lag,可在10g上获得,但没有成功:

select (case when count(*) = sum(case when flag2 not in ('HH', 'EE', 'HS', 'SE')
             then 1 else 0
        end) as return_value
from (select t.*,
             (lag(flag) over (order by dt) || flag) as flag2
      from temp
     ) t;

问题

  1. 有人可以告诉我如何让它发挥作用吗?
  2. COLLECT(见here)在效果方面与lag的比较如何?
  3. 由于

    编辑:

    预期结果

    • EHEEESHEHH必须返回1,因为可以找到以下两个字母(HH|EE|HS|SE)中的至少一个(此处EEHHEHEEESHEHH
    • 如果模式是EHESSSHEHE,则必须返回0,因为HH|EE|HS|SE中找不到以下两个字母模式(EHESSSHEHE)。

    注意:模式(例如EHEEESHEHH),如果内部查询SELECT listagg(FLAG) WITHIN GROUP (ORDER BY DT) as flags FROM TEMP_OUTPUT_OVLP对数据表的结果。

2 个答案:

答案 0 :(得分:2)

如果对任何人都有帮助,那就得到以下工作:

    SELECT DECODE(return_value,0,0,1) result 
    FROM (SELECT 
            SUM(CASE WHEN (flag2 in ('HH', 'EE', 'HS', 'SE'))
                THEN 1 ELSE 0 
                END) AS return_value
    FROM (SELECT
            (lag(flag) over (ORDER BY DT) || flag) AS flag2
              FROM TEMP_OUTPUT_OVLP)
    ) t;

它将返回1

|----------|----------|
|  DT      |  FLAG    |
|----------|----------|
|  10      |  E       |
|  20      |  H       |
|  30      |  E       |
|  40      |  E       |
|  50      |  E       |
|  60      |  S       |
|  70      |  H       |
|  75      |  E       |
|  80      |  H       |
|  100     |  H       |
|----------|----------|

0代表:

|----------|----------|
|  DT      |  FLAG    |
|----------|----------|
|  10      |  E       |
|  20      |  H       |
|  30      |  E       |
|  40      |  H       |
|  50      |  E       |
|  60      |  S       |
|  70      |  H       |
|  75      |  E       |
|  80      |  H       |
|  100     |  E       |
|----------|----------|

正如所料。

答案 1 :(得分:1)

并不重要(因为你已经找到了解决方案),但是 - 也许你会对另外两种聚合10g值的选项感兴趣。

这个安全使用:

SQL> select rtrim(xmlagg(xmlelement(e, dname ||',') order by deptno).extract('//text()'), ',') depts
  2  from dept;

DEPTS
--------------------------------------------------------------------------------
ACCOUNTING,RESEARCH,SALES,OPERATIONS

WM_CONCAT未记录,因此您最好不要使用它,因为Oracle可能决定将其从未来的版本中删除,以便...向后兼容。

SQL> select wm_concat(dname) depts
  2  from dept;

DEPTS
--------------------------------------------------------------------------------
ACCOUNTING,RESEARCH,SALES,OPERATIONS

SQL>