首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UNNEST多值?

UNNEST多值?
EN

Stack Overflow用户
提问于 2018-09-05 01:21:22
回答 3查看 6.1K关注 0票数 1

我正试着用另一张桌子做一张桌子。原始表中有一行如下所示:

代码语言:javascript
复制
------------------------
| col1 | col 2 | col 3 |
------------------------
| item | a,b,c | 1,2,3 |
------------------------

我试着把这一行放到一个表中,如下所示:

代码语言:javascript
复制
------------------------
| col1 | col 2 | col 3 |
------------------------
| item |   a   |   1   |
------------------------
| item |   b   |   2   |
------------------------
| item |   c   |   3   |
------------------------

所以基本上我在尝试同时取消两个逗号分隔的行。到目前为止,我想出的最好的方法是分别对每一列进行UNNEST,然后尝试合并两个结果表(我也在为此而苦苦挣扎),但理想情况下,我希望在一个步骤中完成这一步。

下面是我对UNNEST的查询,每次查询一行:

代码语言:javascript
复制
SELECT
  col1, col2, col3
FROM 
  tableName,
UNNEST(SPLIT(col2)) AS col2

下面是我将UNNEST作为子查询的尝试,但它给出了大量的结果:

代码语言:javascript
复制
SELECT sub.*
FROM (
  SELECT
    col1, col2, col3 AS col3
  FROM 
    tableName,
  UNNEST(SPLIT(col2)) AS col2
  WHERE
    randomCol = 'something'
  ) sub,
UNNEST(SPLIT(sub.col3)) AS col3
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-09-05 09:01:03

您可以使用unnest(split(col))策略,但不要同时交叉联接这两列。您的回答暗示了逗号分隔值的隐式顺序,因此您需要建立一个字段(下面的RowNumber)来指示这种顺序。

代码语言:javascript
复制
with Expanded2 as (
  select
    tableName.col1,
    col2.col2,
    row_number() over (partition by col1 order by 1) RowNumber
  from
    tableName,
    unnest(split(col2)) col2
), Expanded3 as (
  select
    tableName.col1,
    col3.col3,
    row_number() over (partition by col1 order by 1) RowNumber
  from
    tableName,
    unnest(split(col3)) col3
)
select
  Expanded2.col1,
  Expanded2.col2,
  Expanded3.col3
from
  Expanded2
  full outer join Expanded3 on 
    Expanded2.col1 = Expanded3.col1
    and Expanded2.RowNumber = Expanded3.RowNumber

我不确定您的rdbms如何有效地处理空窗口分区。上面的代码可以在PostgreSQL中运行。SQL Server将需要order by (select null)。Ymmv.

票数 0
EN

Stack Overflow用户

发布于 2018-09-05 15:51:57

标准允许将多个值传递给unnest()函数。

因此,下面的代码应该可以工作(在Postgres中也是如此)

代码语言:javascript
复制
select d.col1, 
       t.*
from data d
  cross join unnest(string_to_array(d.col2, ','), string_to_array(d.col3, ',')) as t(col1, col2) 

这也正确地处理了列表中不同数量的元素。

但是,我不知道您的专有DBMS是否支持这一点。

在线示例:http://rextester.com/XPN48947

票数 4
EN

Stack Overflow用户

发布于 2018-09-05 03:14:47

说原始表有“一行”:你的意思是正好有一行吗?如果是,这就解决了这个问题:

代码语言:javascript
复制
with 
num_rows_ as (
  select length( regexp_replace((select b from t), '[^,]+')) + 1 value_ from dual),
a_ as (
  select a from t),
b_ as (
  select regexp_substr( (select b from t), '[^,]', 1, level ) b,rownum rownum_
  from dual
  connect by level <= (select value_ from num_rows_)),
c_ as (
  select regexp_substr( (select c from t), '[^,]', 1, level ) c,rownum rownum_
  from dual
  connect by level <= (select value_ from num_rows_))  
select a_.a,b_.b,c_.c 
  from a_ 
  full outer join b_ on 1=1
  inner join c_ on b_.rownum_ = c_.rownum_;

http://sqlfiddle.com/#!4/f795b9/29

或者更短,在一个步骤中:

代码语言:javascript
复制
with a_ as
(select a from t),
b_c_ as (
  select regexp_substr( (select b from t), '[^,]', 1, level ) b,regexp_substr( (select c from t), '[^,]', 1, level ) c
  from dual
  connect by level <= (length( regexp_replace((select b from t), '[^,]+')) + 1)
)
select * from a_ cross join b_c_;

http://sqlfiddle.com/#!4/f795b9/32/0

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52171246

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档