我在PostgreSQL中有两个表。捐赠桌子和带桌子的桌子。我想为每个功能分配一个donation_id,但是应该将一些donation_id分配给表中的多个记录,其中的功能基于捐赠表中的ammount。
例如:有人捐赠10,然后每2个功能应分配给功能表中具有相同donation_id的特定donation_id = 5条记录。
我正在寻找更新声明,因为这些功能已经存在并且它们都具有唯一值。将哪个特征分配给哪个捐赠并不重要,只有数量很重要。
捐赠:
donation_id | ammount
=====================
001 | 10
002 | 4
特点:
feature_id | donation_id | owned
=================================
001 | 000 | false
002 | 000 | false
003 | 000 | false
004 | 000 | false
005 | 000 | false
006 | 000 | false
007 | 000 | false
008 | 000 | false
输出:
feature_id | donation_id | owned
=================================
001 | 001 | true
002 | 001 | true
003 | 001 | true
004 | 001 | true
005 | 001 | true
006 | 002 | true
007 | 002 | true
008 | 000 | false
答案 0 :(得分:0)
您可以使用Common Table Expression(或两个临时表,或一些子查询和冗余),玩几个技巧:
CROSS JOIN
(即笛卡尔积)和generate_series
来获取重复的行。 [我们添加一个row_number()列以便能够区分它们。] feature_id
和LIMIT
行数来选择一定数量的功能。我们再次添加row_number()列以区分它们。因此,以下代码可以解决问题:
-- Get a (virtual) table with "donation_id" repeated as many times
-- as (amount/2). Trick: use a CROSS JOIN with generate_series
WITH new_features AS
(
SELECT
donation_id, row_number() over () AS rn
FROM
donations
CROSS JOIN generate_series(1, amount/2) AS g(i)
),
-- Right now we know how many rows we want to UPDATE.
-- The next SELECT chooses them. Trick: computed LIMIT
to_update AS
(
SELECT
feature_id, row_number() over () AS rn
FROM
features
WHERE
NOT owned
ORDER BY
feature_id -- This is arbitrary, it could even not be sorted.
LIMIT
(SELECT count(*) FROM new_features)
)
-- ... and finally
UPDATE
features
SET
donation_id = new_features.donation_id, owned = true
FROM
to_update
JOIN new_features USING(rn)
WHERE
features.feature_id = to_update.feature_id
RETURNING
features.feature_id, features.donation_id, features.owned ;
您可以在RexTester
查看注意:
feature_id
是主键(或备用键:唯一且不为空)。如果不是这样,则需要适当的PK。owned
表示donation_id
时,可能只有一个NULL
而不是not owned
列。这样可以保存一个不必更新的列。