【问题标题】:how to calc ranges in oracleoracle如何计算范围
【发布时间】:2010-08-27 12:20:40
【问题描述】:

我有一个定义范围的表格,例如:

START | END | MAP
1     | 10  | A
11    | 15  | B
...

如何查询该表,结果将是

ID | MAP
1  | A
2  | A
3  | A
4  | A
5  | A
6  | A
7  | A
8  | A
9  | A
10 | A
11 | B
12 | B
13 | B
14 | B
15 | B
...

我敢打赌,这很简单...感谢您的帮助

f.

【问题讨论】:

  • 数据(范围表中)可以这样吗? (我的意思是,当 C 扩展到另一个范围时。) 开始 |结束 |地图 1 | 10 | 11 | 15 | 5 | 14 | C

标签: sql oracle range


【解决方案1】:
 select * from Table, (Select Level as Id from dual connect by Level <= (Select Max(End)      from Table)) t
 Where  t.Id between rr.Start and rr.End
 Order by Map, Start, Id

【讨论】:

  • 我在这里得到了很多很好的答案,特别是那个写大文章的人。但这一个很简单,排序并做到了!谢了哥们! f.
【解决方案2】:

这个解决方案乍一看看起来很复杂,但通常可以解决任何范围。解决可能与任何其他范围干扰的 VALUE 问题。

首先创建示例表并插入数据:

create table test_table (col_START NUMBER, col_END NUMBER, col_MAP CHAR(1));
insert into test_table(col_START, col_END, col_MAP) values(1,10,'A');
insert into test_table(col_START, col_END, col_MAP) values(11,15,'B');
insert into test_table(col_START, col_END, col_MAP) values(5,12,'C');

现在数据如下所示:

START | END | MAP
1     | 10  | A
11    | 15  | B
5     | 12  | C

现在创建对象类型:

CREATE TYPE SampleType AS OBJECT
(
  id number,
  map_string varchar2(2000)
)
/

CREATE TYPE SampleTypeSet AS TABLE OF SampleType
/

并且还创建了流水线功能:

CREATE OR REPLACE FUNCTION GET_DATA RETURN SampleTypeSet
PIPELINED
IS
    l_one_row SampleType := SampleType(NULL, NULL);

BEGIN

    FOR cur_data IN (select col_START, col_END, col_MAP from test_table) LOOP
        FOR i IN cur_data.col_START..cur_data.col_END LOOP
            l_one_row.id := i;
            l_one_row.map_string := cur_data.col_MAP;
            PIPE ROW(l_one_row);
        END LOOP;
    END LOOP;

    RETURN;
END GET_DATA;
/

终于可以使用简单查询了:

SELECT * FROM TABLE(GET_DATA());

或者创建并从视图中选择它(如果你想隐藏 OBJECT 实现):

CREATE VIEW VIEW_ALL_DATA AS SELECT * FROM TABLE(GET_DATA());
SELECT * FROM VIEW_ALL_DATA;

基于此我的文章:

http://martin-mares.cz/2010/08/oracle-db-pipelined-function/

【讨论】:

    【解决方案3】:

    我可以给你一个肮脏的解决方案。但是请不要笑我:(

    1. 准备一个虚拟表,比如表 DUMMY,它只包含一个字段 (DUMMY_ID),其值为 1..n,其中 n 足以解决您的问题。我们以 n = 100 为例。
    2. 加入这两个表,即您的实际表和 DUMMY 表。就像这样:

      选择 DUMMY_ID, MAPDUMMY, (选择STARTENDMAP FROM ACTUAL)作为ACTUAL 在哪里 DUMMY_IDSTARTEND 之间

    请注意,上面给出的查询是 MySQL。我很长时间没有使用 Oracle,但你肯定明白了。

    【讨论】:

      【解决方案4】:
      WITH    r AS
              (
              SELECT   MAX(end - start) + 1 AS mr
              FROM     ranges
              ),
              series AS
              (
              SELECT   level - 1 AS l
              FROM     dual
              CONNECT BY
                       level <=
                       (
                       SELECT  mr
                       FROM    r
                       )
              )
      SELECT  start + l, map
      FROM    ranges
      JOIN    series
      ON      l <= end - start
      

      PostgreSQL,你可以这样做:

      SELECT  map, generate_series(start, end)
      FROM    ranges
      

      更新:

      在您的样本数据上进行了测试:

      WITH    ranges AS
              (
              SELECT  1 AS f_start, 10 AS f_end, 'A' AS map
              FROM    dual
              UNION ALL
              SELECT  11 AS f_start, 15 AS f_end, 'B' AS map
              FROM    dual
              ),
              r AS
              (
              SELECT   MAX(f_end - f_start) + 1 AS mr
              FROM     ranges
              ),
              series AS
              (
              SELECT   level - 1 AS l
              FROM     dual
              CONNECT BY
                       level <=
                       (
                       SELECT  mr
                       FROM    r
                       )
              )
      SELECT  f_start + l, map
      FROM    ranges
      JOIN    series
      ON      l <= f_end - f_start
      ORDER BY
              2, 1
      

      【讨论】:

      • @flpgdt:查看帖子更新,它适用于您提供的数据。
      • 希望 Oracle 实现 generate_series - 人们可能真正理解我编写的 SQL。 . . .
      猜你喜欢
      • 2017-08-30
      • 1970-01-01
      • 2011-08-17
      • 2016-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-12
      相关资源
      最近更新 更多