我在vertica db中有以下表格:
+-------+-------+-------+
| Item1 | Item2 | Item3 |
+-------+-------+-------+
| A | B | S |
| S | C | D |
| E | F | S |
+-------+-------+-------+
每行代表一次交易(例如在商店购物)。我正在寻找一种可扩展的方法来删除表中的所有S
项,而不是减少表来获得这个:
+-------+-------+
| Item1 | Item2 |
+-------+-------+
| A | B |
| D | C |
| E | F |
+-------+-------+
新表中行的顺序并不重要。
附注:表格中的每一行都有S
项,因此无需担心null
条目。
跟进:如果我想同时删除n个项目,有什么比运行n个问题的SQL查询更快的方法呢?
一种可能的解决方案是将术语0000
替换或添加到相关项目中。然后按字母数字排序每一行并删除第一列,但我想知道是否有更优雅的方式。
答案 0 :(得分:1)
可能有多种方法可以做到这一点。我会先将S
转换为NULL
。然后COALESCE
删除NULL
,只留下两个值。然后我会使用LEAST
和GREATEST
对这两个值进行排序,以便获得干净的输出。
注意COALESCE
我只是颠倒了顺序,以便在所有情况下(假设每个元组只有一个S
值)这两个项目将是不同的。
with s_filtered as (
select nullif(Item1,'S') Item1,
nullif(Item2,'S') Item2,
nullif(Item3,'S') Item3
from mytable
)
select distinct least(coalesce(Item1,Item2)) Item1,
greatest(coalesce(Item3,Item2)) Item2
from s_filtered
我不确定在这种情况下我是否理解问题的可扩展部分。如果你的意思是你想拥有超过3个项目,那么......这种方法不会很好。你可以这样做(减去排序,你必须做预处理),但它可能是很多创意合并。
或者,您可以在过滤掉S
类型后进行规范化并执行某种分析工作。这样可以更好地支持更多项目。
示例如果您有6个项目,其中一个S
(请注意,您需要将内容与ID绑在一起):
with ordered_mytable as (
select id, item, row_number() over (partition by id order by item) rn
from mytable
where item <> 'S'
)
select id,
max(decode(rn,1,item)) Item1,
max(decode(rn,2,item)) Item2,
max(decode(rn,3,item)) Item3,
max(decode(rn,4,item)) Item4,
max(decode(rn,5,item)) Item5
from ordered_mytable
group by id
答案 1 :(得分:0)
好的,我设法以一种时髦的方式解决。
使用||
删除您不想要的字符串部分
使用SPLIT_PART
以下是查询:
SELECT
SPLIT_PART(replace, ';', 2) AS c1,
SPLIT_PART(replace, ';', 3) AS c2
FROM
(SELECT replace ( ';'|| item1 ||';'|| item2 ||';'|| item3 , ';S' , '')
FROM my_table ) AS temp
我认为这个查询的方式可以很容易地为更大的表生成(例如使用python),并且它不涉及创建临时表。