在 postgresql 的单个查询中使用 WITH + DELETE 子句
Using WITH + DELETE clause in a single query in postgresql
我有以下 table 结构,对于一个名为 listens
的 table 和 PRIMARYKEY on (uid,timestamp)
Column | Type | Modifiers
----------------+-----------------------------+------------------------------------------------------
id | integer | not null default nextval('listens_id_seq'::regclass)
uid | character varying | not null
date | timestamp without time zone |
timestamp | integer | not null
artist_msid | uuid |
album_msid | uuid |
recording_msid | uuid |
json | character varying |
我需要删除特定用户 (uid) 的所有条目,这些条目早于最大时间戳,例如 max 是 123456789(以秒为单位),delta 是 100000,然后,所有早于 max-100000.
的记录
当 table 包含单个用户时,我设法创建了一个查询,但我无法制定它以适用于数据库中的每个用户。此操作需要对数据库中的每个用户进行。
WITH max_table as (
SELECT max(timestamp) - 10000 as max
FROM listens
GROUP BY uid)
DELETE FROM listens
WHERE timestamp < (SELECT max FROM max_table);
有什么解决办法吗?
我想你所需要的就是使它成为一个相关的子查询:
WITH max_table as (
SELECT uid, max(timestamp) - 10000 as mx
FROM listens
GROUP BY uid
)
DELETE FROM listens
WHERE timestamp < (SELECT mx
FROM max_table
where max_table.uid = listens.uid);
顺便说一句:timestamp
是一个糟糕的列名称,尤其是不包含时间戳值的列。一个原因是因为它也是一个关键字,但更重要的是它没有记录该列包含的内容。注册时间戳?过期时间戳?最后一个活动时间戳?
或者,您可以使用 EXISTS()
来避免 MAX()
DELETE FROM listens d
WHERE EXISTS (
SELECT * FROM listens x
WHERE x.uid = d.uid
AND x.timestamp >= d.timestamp + 10000
);
顺便说一句:timestamp
是一个丑陋的列名,因为它也是一个类型名。
我有以下 table 结构,对于一个名为 listens
的 table 和 PRIMARYKEY on (uid,timestamp)
Column | Type | Modifiers
----------------+-----------------------------+------------------------------------------------------
id | integer | not null default nextval('listens_id_seq'::regclass)
uid | character varying | not null
date | timestamp without time zone |
timestamp | integer | not null
artist_msid | uuid |
album_msid | uuid |
recording_msid | uuid |
json | character varying |
我需要删除特定用户 (uid) 的所有条目,这些条目早于最大时间戳,例如 max 是 123456789(以秒为单位),delta 是 100000,然后,所有早于 max-100000.
的记录当 table 包含单个用户时,我设法创建了一个查询,但我无法制定它以适用于数据库中的每个用户。此操作需要对数据库中的每个用户进行。
WITH max_table as (
SELECT max(timestamp) - 10000 as max
FROM listens
GROUP BY uid)
DELETE FROM listens
WHERE timestamp < (SELECT max FROM max_table);
有什么解决办法吗?
我想你所需要的就是使它成为一个相关的子查询:
WITH max_table as (
SELECT uid, max(timestamp) - 10000 as mx
FROM listens
GROUP BY uid
)
DELETE FROM listens
WHERE timestamp < (SELECT mx
FROM max_table
where max_table.uid = listens.uid);
顺便说一句:timestamp
是一个糟糕的列名称,尤其是不包含时间戳值的列。一个原因是因为它也是一个关键字,但更重要的是它没有记录该列包含的内容。注册时间戳?过期时间戳?最后一个活动时间戳?
或者,您可以使用 EXISTS()
来避免 MAX()DELETE FROM listens d
WHERE EXISTS (
SELECT * FROM listens x
WHERE x.uid = d.uid
AND x.timestamp >= d.timestamp + 10000
);
顺便说一句:timestamp
是一个丑陋的列名,因为它也是一个类型名。