在一列内转换多个值

时间:2013-07-09 15:06:26

标签: sql oracle report oracle-apex lov

我在Oracle Apex 4.2中工作。我有两张桌子:

我有简单的报告来构建

select id, name, location_id from tablel1
 -----------------------------------
| ID   |  NAME   |  PROJECT_ID    |
-----------------------------------
|  1   |   P1    | 23:45:56       |
|  2   |   P2    |    23          |
|  3   |   P3    |    45:65       |
-----------------------------------

------------------------------------------
| ID   |  NAME        |  SITE            |
------------------------------------------
|  23  |   Orlando    |    SITE1         |
|  45  |   Arizona    |    SITE2         |
|  65  |   Maimi      |    SITE3         |
------------------------------------------

然而,我遇到的问题是location_id只保存有关id的信息,因此需要查找不同的表以获取两列的concat值(名称||' - '|| site)。

虽然还有另一个曲线球,但它很简单:location_id保持穿梭的结果,所以它由像34:45:56:67这样的值填充。我需要将其转换为:

奥兰多 - 亚利桑那州SITE1 - 迈阿密SITE2 - SITE3

所以这些结果都会在报告的一行中返回

由于这是报告,因此可以通过以下方式完成:将列报告转换为“基于LOV显示为文本”,构建生成SQL语句并循环通过值的PL / SQL块等等。

我尝试了很多方法,但我的想法和时间都用完了,解决了这个问题。任何帮助非常感谢。

3 个答案:

答案 0 :(得分:2)

仅限SQL(Oracle 11g):

  select x.id, x.name, listagg(t2.name || t2.site, ', ') within group (order by t2.id)
  from 
  (
    select distinct t1.id, t1.name, regexp_substr(t1.project_id, '[^:]+', 1, level) id_site
    from tablel1 t1
    connect by level <= regexp_count(t1.project_id, ':') + 1
  ) x, table22 t2
  where t2.id = x.id_site
  group by x.id, x.name

这给出了:

1   P1  Orlando - SITE1, Arizona - SITE2, Miami - SITE3
2   P2  Orlando - SITE1
3   P3  Arizona - SITE2, Miami - SITE3

答案 1 :(得分:1)

这是程序:

DECLARE
  CURSOR c (p_id  NUMBER) IS
    SELECT NAME||' - '||SITE
      FROM TABLE2
     WHERE ID = p_id;
  l_tsv     VARCHAR2(1000) := '23:45:56';
  l_item    NUMBER;
  lc_t      VARCHAR(200);
  lc_result VARCHAR2(4000);
BEGIN
  FOR i IN 1 .. LENGTH(l_tsv) - LENGTH(REPLACE(l_tsv, ':', '')) + 1 LOOP
    l_item := REGEXP_SUBSTR(l_tsv, '[^:]+', 1, i);
    OPEN c (l_item);
    FETCH c INTO lc_t;
    CLOSE c;
    lc_result := lc_result ||', '||lc_t;
  END LOOP;
  lc_result := SUBSTR(lc_result,3);
  dbms_output.put_line(lc_result); 
END;

<强>更新

功能:

CREATE OR REPLACE FUNCTION some_name(l_tsv VARCHAR2) RETURN VARCHAR2 IS
  CURSOR c (p_id  NUMBER) IS
    SELECT NAME||' - '||SITE
      FROM TABLE2
     WHERE ID = p_id;
  l_item    NUMBER;
  lc_t      VARCHAR(200);
  lc_result VARCHAR2(4000);
BEGIN
  FOR i IN 1 .. LENGTH(l_tsv) - LENGTH(REPLACE(l_tsv, ':', '')) + 1 LOOP
    l_item := REGEXP_SUBSTR(l_tsv, '[^:]+', 1, i);
    OPEN c (l_item);
    FETCH c INTO lc_t;
    CLOSE c;
    lc_result := lc_result ||', '||lc_t;
  END LOOP;
  lc_result := SUBSTR(lc_result,3);
  RETURN (lc_result);
END some_name;

答案 2 :(得分:0)

正如您在评论中所说:使用table1和location_id中的ID创建第三个表。然后只需在查询中连接这些表。 但我没有理解:

  

我需要将其转换为:

     

奥兰多 - 亚利桑那州SITE1 - 迈阿密SITE2 - SITE3

     

所以这些结果都会在报告的一行中返回

是真正的要求吗?如果将其转换为

,该怎么办?
P1 - Orlando - SITE1
P1 - Arizona - SITE2 
P1 - Maimi   - SITE3
P2 - Orlando - SITE1
P3 - Arizona - SITE2 
P3 - Maimi   - SITE3

?如果是这样,您将需要一个简单的连接。或者在没有连接的情况下生成报告,并且从另一个表中创建一个字段作为查找。