【问题标题】:Returning any element that isn’t contained in two columns SQL返回不包含在两列 SQL 中的任何元素
【发布时间】:2020-11-05 12:32:34
【问题描述】:

我在一个表中有两列,我想创建第三列,其中包含两列中未包含的任何元素。例如:两列的第一行如下所示:

Col1: [‘apple’,’banana’,’orange’,’pear’]
Col2: [‘apple’,’banana’]

它会返回:

Col3: [‘orange’, ‘pear’]

本质上与array_intersect 函数相反。我在php中看到过array_diff,所以我想知道sql中是否有等效的函数?

【问题讨论】:

  • 不,上面的示例显示了表格的第一行。每行由一个数组组成,每个数组都有不同数量的元素。它们是使用“collect_set”函数形成的数组

标签: sql arrays string hiveql unnest


【解决方案1】:

分解 col1 并使用 array_contains+case 语句,再次使用 collect_set 或 collect_list 组装数组。

演示:

with your_data as (--Test data. Use your table instead of this
select stack(1,
array('apple','banana','orange','pear'),
array('apple','banana')
) as (col1, col2)
)

select col1, col2, 
       collect_set(case when array_contains(t.col2, e.col1_elem) then null else e.col1_elem end) as col3
  from your_data t
       lateral view explode(t.col1) e as col1_elem
group by col1,  col2

结果:

col1                                 col2                col3
["apple","banana","orange","pear"]  ["apple","banana"]  ["orange","pear"]

【讨论】:

    【解决方案2】:

    如果你有一个主键,那么我认为这会做你想要的:

    select t.pk, collect_set(case when c2.el is null then c1.el end)
    from (t lateral view
          explode(t.col1) c1 as el 
         ) left join
         (t t2 lateral view
          explode(t2.col2) c2 as el
         )
         on t.pk = t2.pk and
            c1.el = c2.el
    group by t.pk;
    

    【讨论】:

      猜你喜欢
      • 2019-07-21
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      • 1970-01-01
      • 2015-02-19
      • 1970-01-01
      • 2016-12-06
      • 1970-01-01
      相关资源
      最近更新 更多