SQL - 对一列进行逆透视结果

发布于 2024-12-10 16:12:13 字数 1262 浏览 0 评论 0原文

在 Oracle 10g 上,假设我有以下列:

col
------------------------------------------------------------------------------------------------
[1,98]([1,81]([6,100828],[6,101260]),[1,81]([6,100529],[6,101259]),[1,81]([6,101709],[6,100474]))

并且我想显示此结果:

col
------
100828
101260
100529
101259
101709
100474

是否可以使用 SQL 查询显示此结果?

实际上我尝试过:

SELECT SUBSTR(col, INSTR(col, ',', 1, 3) + 1, 6) exp_1,
       SUBSTR(col, INSTR(col, ',', 1, 5) + 1, 6) exp_2,
       SUBSTR(col, INSTR(col, ',', 1, 8) + 1, 6) exp_3,
       SUBSTR(col, INSTR(col, ',', 1, 10) + 1, 6) exp_4,
       SUBSTR(col, INSTR(col, ',', 1, 13) + 1, 6) exp_5,
       SUBSTR(col, INSTR(col, ',', 1, 15) + 1, 6) exp_6
  FROM (SELECT '[1,98]([1,81]([6,100828],[6,101260]),[1,81]([6,100529],[6,101259]),[1,81]([6,101709],[6,100474]))' col
          FROM dual) ; 

EXP_1  EXP_2  EXP_3  EXP_4  EXP_5  EXP_6
------ ------ ------ ------ ------ ------
100828 101260 100529 101259 101709 100474

但是,返回的 exp_% 的数量可能是可变的并且总是成对的,这意味着另一行可以返回 8 exp_% :

SUBSTR(col, INSTR(col, ',', 1, 18) + 1, 6) exp_7 ,
SUBSTR(col, INSTR(col, ',', 1, 20) + 1, 6) exp_8

当 exp_% 的数量固定时的建议也非常受欢迎!

谢谢。

on Oracle 10g, say i have this following column :

col
------------------------------------------------------------------------------------------------
[1,98]([1,81]([6,100828],[6,101260]),[1,81]([6,100529],[6,101259]),[1,81]([6,101709],[6,100474]))

and i want to display this result:

col
------
100828
101260
100529
101259
101709
100474

Is it possible to display this result with an SQL query?

Actually what i tried :

SELECT SUBSTR(col, INSTR(col, ',', 1, 3) + 1, 6) exp_1,
       SUBSTR(col, INSTR(col, ',', 1, 5) + 1, 6) exp_2,
       SUBSTR(col, INSTR(col, ',', 1, 8) + 1, 6) exp_3,
       SUBSTR(col, INSTR(col, ',', 1, 10) + 1, 6) exp_4,
       SUBSTR(col, INSTR(col, ',', 1, 13) + 1, 6) exp_5,
       SUBSTR(col, INSTR(col, ',', 1, 15) + 1, 6) exp_6
  FROM (SELECT '[1,98]([1,81]([6,100828],[6,101260]),[1,81]([6,100529],[6,101259]),[1,81]([6,101709],[6,100474]))' col
          FROM dual) ; 

EXP_1  EXP_2  EXP_3  EXP_4  EXP_5  EXP_6
------ ------ ------ ------ ------ ------
100828 101260 100529 101259 101709 100474

however, the number of returned exp_% could be variable and are always pair, which means one another row could return 8 exp_% :

SUBSTR(col, INSTR(col, ',', 1, 18) + 1, 6) exp_7 ,
SUBSTR(col, INSTR(col, ',', 1, 20) + 1, 6) exp_8

Suggestions when number of exp_% is fix are more than welcome too!

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

兲鉂ぱ嘚淚 2024-12-17 16:12:13

假设您的表名为“foo”,列名为“col”:

with q as (
    select ','||regexp_replace(
        regexp_replace(
            regexp_replace(
                regexp_replace(col, '[[0-9,]*]\(', ''), 
                    '\[[0-9],', ''), 
                '[])]', ','), 
        ',,+', 
        ',') a from foo
) 
select data 
  from (select substr(a, instr(a, ',', 1, rownum) + 1, 6) data 
          from q,
               (select 1 from q connect by level < length(regexp_replace(a, '[0-9]', '')))
       )
;

以下是解释。这很快就会变得复杂,并且可能无法很好地扩展,因此买家要小心。

首先,我想删除 '[1,98](' 字段。

  1  with q as (
  2  select
  3          regexp_replace(col, '[[0-9,]*]\(', '')
  4  from foo
  5  )
  6* select * from q

REGEXP_REPLACE(COL,'[[0-9,]*]\(','')
------------------------------------------------------------------------------------------------------------------------------------
[6,100828],[6,101260])[6,100529],[6,101259])[6,101709],[6,100474]))

接下来,我想删除字段的 '[n,' 部分。

  1  with q as (
  2  select
  3      regexp_replace(
  4          regexp_replace(col, '[[0-9,]*]\(', ''),
  5          '\[[0-9],', ''
  6      ) a from foo
  7  )
  8* select * from q

A
------------------------------------------------------------------------------------------------------------------------------------
100828],101260])100529],101259])101709],100474]))

现在删除所有 ']' 和 ')'

  1  with q as (
  2  select
  3      regexp_replace(
  4      regexp_replace(
  5          regexp_replace(col, '[[0-9,]*]\(', ''),
  6          '\[[0-9],', ''),
  7          '[])]', ',')
  8       a from foo
  9  )
 10* select * from q

A
------------------------------------------------------------------------------------------------------------------------------------
100828,,101260,,100529,,101259,,101709,,100474,,,

删除重复的逗号并在前面加上逗号。

  1  with q as (
  2  select ','||regexp_replace(
  3      regexp_replace(
  4      regexp_replace(
  5          regexp_replace(col, '[[0-9,]*]\(', ''),
  6          '\[[0-9],', ''),
  7          '[])]', ','),
  8      ',,+',
  9      ',') a from foo
 10  )
 11* select * from q

A
------------------------------------------------------------------------------------------------------------------------------------
,100828,101260,100529,101259,101709,100474,

找出它们有多少个字段并为每个字段创建一行。

  1  with q as (
  2  select ','||regexp_replace(
  3      regexp_replace(
  4      regexp_replace(
  5          regexp_replace(col, '[[0-9,]*]\(', ''),
  6          '\[[0-9],', ''),
  7          '[])]', ','),
  8      ',,+',
  9      ',') a from foo
 10  )
 11* select 1 from q connect by level < length(regexp_replace(a, '[0-9]', ''))

     1
----------
     1
     1
     1
     1
     1
     1
     1

使用 q 进行笛卡尔连接(请注意,如果表中有多于一行,则这将不起作用。)和一个子字符串以获得最终答案。

  1  with q as (
  2  select ','||regexp_replace(
  3      regexp_replace(
  4      regexp_replace(
  5          regexp_replace(col, '[[0-9,]*]\(', ''),
  6          '\[[0-9],', ''),
  7          '[])]', ','),
  8      ',,+',
  9      ',') a from foo
 10  )
 11  select data
 12    from (select substr(a, instr(a, ',', 1, rownum) + 1, 6) data
 13        from q,
 14         (select 1 from q connect by level < length(regexp_replace(a, '[0-9]', '')))
 15*        )

DATA
------
100828
101260
100529
101259
101709
100474


6 rows selected.

Assume your table is named 'foo' with a column name of 'col':

with q as (
    select ','||regexp_replace(
        regexp_replace(
            regexp_replace(
                regexp_replace(col, '[[0-9,]*]\(', ''), 
                    '\[[0-9],', ''), 
                '[])]', ','), 
        ',,+', 
        ',') a from foo
) 
select data 
  from (select substr(a, instr(a, ',', 1, rownum) + 1, 6) data 
          from q,
               (select 1 from q connect by level < length(regexp_replace(a, '[0-9]', '')))
       )
;

Here's the explanation. This gets complex quickly and probably wouldn't scale very well so buyer beware.

First I want to get rid of the '[1,98](' fields.

  1  with q as (
  2  select
  3          regexp_replace(col, '[[0-9,]*]\(', '')
  4  from foo
  5  )
  6* select * from q

REGEXP_REPLACE(COL,'[[0-9,]*]\(','')
------------------------------------------------------------------------------------------------------------------------------------
[6,100828],[6,101260])[6,100529],[6,101259])[6,101709],[6,100474]))

Next I want to get rid of the '[n,' portion of the fields.

  1  with q as (
  2  select
  3      regexp_replace(
  4          regexp_replace(col, '[[0-9,]*]\(', ''),
  5          '\[[0-9],', ''
  6      ) a from foo
  7  )
  8* select * from q

A
------------------------------------------------------------------------------------------------------------------------------------
100828],101260])100529],101259])101709],100474]))

Now get rid of all ']' and ')'

  1  with q as (
  2  select
  3      regexp_replace(
  4      regexp_replace(
  5          regexp_replace(col, '[[0-9,]*]\(', ''),
  6          '\[[0-9],', ''),
  7          '[])]', ',')
  8       a from foo
  9  )
 10* select * from q

A
------------------------------------------------------------------------------------------------------------------------------------
100828,,101260,,100529,,101259,,101709,,100474,,,

Get rid of duplicate commas and prepend with a comma.

  1  with q as (
  2  select ','||regexp_replace(
  3      regexp_replace(
  4      regexp_replace(
  5          regexp_replace(col, '[[0-9,]*]\(', ''),
  6          '\[[0-9],', ''),
  7          '[])]', ','),
  8      ',,+',
  9      ',') a from foo
 10  )
 11* select * from q

A
------------------------------------------------------------------------------------------------------------------------------------
,100828,101260,100529,101259,101709,100474,

Figure out how many fields their are and create a row for each.

  1  with q as (
  2  select ','||regexp_replace(
  3      regexp_replace(
  4      regexp_replace(
  5          regexp_replace(col, '[[0-9,]*]\(', ''),
  6          '\[[0-9],', ''),
  7          '[])]', ','),
  8      ',,+',
  9      ',') a from foo
 10  )
 11* select 1 from q connect by level < length(regexp_replace(a, '[0-9]', ''))

     1
----------
     1
     1
     1
     1
     1
     1
     1

Do a cartesian join with q (note this won't work if there's more than one row in your table.) and a substring to get your final answer.

  1  with q as (
  2  select ','||regexp_replace(
  3      regexp_replace(
  4      regexp_replace(
  5          regexp_replace(col, '[[0-9,]*]\(', ''),
  6          '\[[0-9],', ''),
  7          '[])]', ','),
  8      ',,+',
  9      ',') a from foo
 10  )
 11  select data
 12    from (select substr(a, instr(a, ',', 1, rownum) + 1, 6) data
 13        from q,
 14         (select 1 from q connect by level < length(regexp_replace(a, '[0-9]', '')))
 15*        )

DATA
------
100828
101260
100529
101259
101709
100474


6 rows selected.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文