如何在 DELETE 查询中将 postgres 函数结果用作单独的列
How to use postgres function result as a separate column in DELETE query
我必须根据与其中一列上的超长函数应用程序的多重比较来删除 table 中的行。详细一点,我从 base64 解码,做一个子字符串,转换为 json
,获取特定字段,然后将其转换为 inet
。
我正在使用这些 ips 与我的 WHERE
子句中的其他 ips/掩码进行比较。
我遇到的问题是获得实际结果是一个很长的字符串,如果我最后说 ip < foo(bar(baz(quux))) OR ip2 < foo(bar(baz(quux)))
那么用于比较的值最终也会被计算多次。
我正在寻找一种方法来预先计算该值,为其分配一个有意义的名称,然后在我的 WHERE
子句中使用该名称。
谢谢
您可以使用横向连接:
select . . .
from t cross join lateral
(values (foo(bar(baz(quux))) ) v(decoded_value)
where ip < v.decoded_vaue or ip2 < v.decoded_value;
在 Postgres 中,delete
有点棘手。假设你有一个主键:
delete t
using t t2 cross join lateral
(values (foo(bar(baz(t2.quux))) ) v(decoded_value)
where t2.primary_key = t.primary_key and
(t2.ip < v.decoded_vaue or t2.ip2 < v.decoded_value);
您是否考虑过 CTE 的用法?
例如,假设我们有以下 table
CREATE TABLE test_table (
id BIGINT PRIMARY KEY,
some_data INTEGER
);
假设我们要删除表达式结果为
的所有行
some_data % 10
是(>=1 且 <=4)或(>=6 且 <=8)。
在这种情况下,模运算会用模运算替换您的 foo(bar(baz(column_name)))
调用。
简单的方法是编写以下查询:
DELETE FROM test_table
WHERE
(MOD(some_data, 10) >= 1 AND MOD(some_data, 10) <= 4)
OR
(MOD(some_data, 10) >=6 AND MOD(some_data, 10) <= 8);
如您所说,这将多次重新计算同一件事。为了只计算一次,我们可以创建一个CTE
并在删除查询中使用结果。
WITH precalculated_table AS (
SELECT *, mod(some_data, 10) as mod_10_result FROM test_table
)
DELETE FROM test_table WHERE id IN (
SELECT id from precalculated_table
where
(mod_10_result >= 1 and mod_10_result <= 4)
OR
(mod_10_result >= 6 AND mod_10_result <= 8)
);
这样,我们只计算一次,然后在 DELETE
查询的 WHERE
部分使用预先计算的列。
我必须根据与其中一列上的超长函数应用程序的多重比较来删除 table 中的行。详细一点,我从 base64 解码,做一个子字符串,转换为 json
,获取特定字段,然后将其转换为 inet
。
我正在使用这些 ips 与我的 WHERE
子句中的其他 ips/掩码进行比较。
我遇到的问题是获得实际结果是一个很长的字符串,如果我最后说 ip < foo(bar(baz(quux))) OR ip2 < foo(bar(baz(quux)))
那么用于比较的值最终也会被计算多次。
我正在寻找一种方法来预先计算该值,为其分配一个有意义的名称,然后在我的 WHERE
子句中使用该名称。
谢谢
您可以使用横向连接:
select . . .
from t cross join lateral
(values (foo(bar(baz(quux))) ) v(decoded_value)
where ip < v.decoded_vaue or ip2 < v.decoded_value;
在 Postgres 中,delete
有点棘手。假设你有一个主键:
delete t
using t t2 cross join lateral
(values (foo(bar(baz(t2.quux))) ) v(decoded_value)
where t2.primary_key = t.primary_key and
(t2.ip < v.decoded_vaue or t2.ip2 < v.decoded_value);
您是否考虑过 CTE 的用法?
例如,假设我们有以下 table
CREATE TABLE test_table (
id BIGINT PRIMARY KEY,
some_data INTEGER
);
假设我们要删除表达式结果为
的所有行some_data % 10
是(>=1 且 <=4)或(>=6 且 <=8)。
在这种情况下,模运算会用模运算替换您的 foo(bar(baz(column_name)))
调用。
简单的方法是编写以下查询:
DELETE FROM test_table
WHERE
(MOD(some_data, 10) >= 1 AND MOD(some_data, 10) <= 4)
OR
(MOD(some_data, 10) >=6 AND MOD(some_data, 10) <= 8);
如您所说,这将多次重新计算同一件事。为了只计算一次,我们可以创建一个CTE
并在删除查询中使用结果。
WITH precalculated_table AS (
SELECT *, mod(some_data, 10) as mod_10_result FROM test_table
)
DELETE FROM test_table WHERE id IN (
SELECT id from precalculated_table
where
(mod_10_result >= 1 and mod_10_result <= 4)
OR
(mod_10_result >= 6 AND mod_10_result <= 8)
);
这样,我们只计算一次,然后在 DELETE
查询的 WHERE
部分使用预先计算的列。