从随机有序列中提取序列顺序的数字

问题描述 投票:0回答:2

我的数据库qs5中有一个列,其中包含一系列多选选项1-4,它们可以以任意随机顺序出现,由空格分隔,例如: 1 2 44 1

我想将这些选项中的每一个提取到自己的列中,这样我就得到了列qs5c1 - qs5c4,以便上面的示例看起来像

|qs5c1|qs5c2|qs5c3|qs5c4|
|-----|-----|-----|-----|
|  1  |  2  |null |  4  |
|  1  |null |null |  4  |

这是我一直在使用的SQL

substring('1' from position('1' in qs5) for 1) as qs5c1,
substring('2' from position('2' in qs5) for 1) as qs5c2,
substring('3' from position('3' in qs5) for 1) AS qs5c3,
substring('4' from position('4' in qs5) for 1) AS qs5c4

但是我使用上面的数据作为示例返回的是,它只是选取字符串中的第一个字符并跳过其余字符。

|qs5c1|qs5c2|qs5c3|qs5c4|
|-----|-----|-----|-----|
|  1  |null |null |null |
|null |null |null |  4  |

我想当它提取第一个字符时,qs5的长度比以前小1个字符,但是再次说明不能解释为什么第二行跳过1,因为1应该是相同的在提取4之前/之后放置。

谢谢!

postgresql
2个回答
1
投票

问题是,你不是来自substring()qs5,而是文字'1''2'等。所以当然这只会导致文字中的单个字符。如果您使用qs5而不是按预期工作。

SELECT substring(qs5 FROM position('1' IN qs5) FOR 1) qs5c1,
       substring(qs5 FROM position('2' IN qs5) FOR 1) qs5c2,
       substring(qs5 FROM position('3' IN qs5) FOR 1) qs5c3,
       substring(qs5 FROM position('4' IN qs5) FOR 1) qs5c4
       FROM elbat;

db<>fiddle


0
投票

如果它确实是一组固定的值,我会这样做:

select case when '1' = any(string_to_array(qs5, ' ')) then '1' end as qs51,
       case when '2' = any(string_to_array(qs5, ' ')) then '2' end as qs52,
       case when '3' = any(string_to_array(qs5, ' ')) then '3' end as qs53,
       case when '4' = any(string_to_array(qs5, ' ')) then '4' end as qs54,
       case when '5' = any(string_to_array(qs5, ' ')) then '5' end as qs55
from the_table;

在线示例:https://rextester.com/FMR86051

如果你以更动态的方式需要它,你可以使用这样的东西:

select f.options[1] as qs5c1,
       f.options[2] as qs5c2,
       f.options[3] as qs5c3,
       f.options[4] as qs5c4
from the_table t
  cross join lateral (
    select array_agg(x.val order by g.idx) as options
    from generate_series(1,4) g(idx)
      left join unnest(string_to_array(t.qs5, ' ')::int[]) with ordinality as x(val,idx) on g.idx = x.val
  ) f
;

在线示例包含8个元素:https://rextester.com/PMKDW38472

© www.soinside.com 2019 - 2024. All rights reserved.