SQL:通过删除 table 中的指定项目来减少 table
SQL: Reduce table by removing specified Items in a table
我在 vertica 数据库中有以下 table:
+-------+-------+-------+
| Item1 | Item2 | Item3 |
+-------+-------+-------+
| A | B | S |
| S | C | D |
| E | F | S |
+-------+-------+-------+
每一行代表一次交易(例如在商店购物)。我正在寻找一种可扩展的方法来删除 table 中的所有 S
项目,而不是减少 table 以获得此:
+-------+-------+
| Item1 | Item2 |
+-------+-------+
| A | B |
| D | C |
| E | F |
+-------+-------+
新 table 中行的顺序并不重要。
旁注:table 中的每一行都有项目 S
,因此无需担心 null
个条目。
跟进:如果我想同时删除 n 项怎么办,有没有比 运行 问题的 SQL 查询 n 次更快的方法?
一个可能的解决方案是替换或添加到有问题的项目 0000
。比按字母数字对每一行排序并删除第一列,但我想知道是否有更优雅的方法。
可能有多种方法可以做到这一点。我会先将 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
好的,我设法以一种时髦的方式解决了问题。
使用 ||
从所有行创建一个字符串
删除字符串中不需要的部分
使用 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),并且不涉及创建临时表。
我在 vertica 数据库中有以下 table:
+-------+-------+-------+
| Item1 | Item2 | Item3 |
+-------+-------+-------+
| A | B | S |
| S | C | D |
| E | F | S |
+-------+-------+-------+
每一行代表一次交易(例如在商店购物)。我正在寻找一种可扩展的方法来删除 table 中的所有 S
项目,而不是减少 table 以获得此:
+-------+-------+
| Item1 | Item2 |
+-------+-------+
| A | B |
| D | C |
| E | F |
+-------+-------+
新 table 中行的顺序并不重要。
旁注:table 中的每一行都有项目 S
,因此无需担心 null
个条目。
跟进:如果我想同时删除 n 项怎么办,有没有比 运行 问题的 SQL 查询 n 次更快的方法?
一个可能的解决方案是替换或添加到有问题的项目 0000
。比按字母数字对每一行排序并删除第一列,但我想知道是否有更优雅的方法。
可能有多种方法可以做到这一点。我会先将 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
好的,我设法以一种时髦的方式解决了问题。
使用
||
从所有行创建一个字符串
删除字符串中不需要的部分
使用
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),并且不涉及创建临时表。