将新列new_column
添加到现有表rules
后,我想应用一些复杂的迁移逻辑来确定每行的新值(我需要查看另一个表)名为flags
,由rules
间接引用。
Q1。我可以使用JOIN
和CASE
语句完成此操作,还是需要编写pgSQL
函数?
Q2。哪种逻辑方法更好(伪代码):
FOR flag IN flags
FOR app IN applications WHERE app.accountid = flag.accountid
FOR campaign IN campaigns WHERE campaign.applicationid = app.id
FOR rule IN rules WHERE rule.campaignid = campaign.id
SET rule.new_column TO
(CASE flag.new == true AND flag.old == false THEN ‘v2’
CASE flag.new == false AND flag.old == true THEN ‘v1’
ELSE return ‘v0’)
或者这样做更好:
FOR rule IN rules
SELECT campaign FROM campaigns WHERE campaign.id = rule.campaignid
SELECT app FROM applications WHERE app.id = campaign.applicationid
SELECT flag FROM flags where flag.accountid = app.accountid
SET rule.new_column TO
CASE (flag.new = true AND flag.old = false) THEN 'v2'
CASE (flag.new = false AND flag.old = true) THEN 'v1'
ELSE 'v0'
示例:
flags:
accountid | new | old
---------------------
1 |true |true
2 |true |false
applications:
id | accountid
--------------
3 | 1
4 | 2
campaigns:
id | applicationid
------------------
5 | 3
6 | 4
rules:
campaignid | new_column (wanted result)
----------------------
5 | 'v0'
5 | 'v0'
6 | 'v2'
答案 0 :(得分:1)
这应该这样做:
update rules
set new_column = case
when f.new and not f.old then 'v2'
when not f.new and f.old then 'v1'
else 'v0'
end
from campaigns c
join applications a on c.applicationid = a.id
join flags f on a.accountid = f.accountid
where c.id = rules.campaignid;
答案 1 :(得分:0)
我认为我已经通过JOINed查询表达式达到了我想要的效果(感谢@joop)。
我会在这里发布,以防它对其他人有用:
UPDATE
rules AS r
SET
rbversion =
CASE
WHEN f.new = TRUE AND f.old = FALSE THEN 'v2'
WHEN f.new = FALSE AND f.old = TRUE THEN 'v1'
ELSE 'v0'
END
FROM
flags AS f,
campaigns AS c,
applications AS a
WHERE
c.id = r.campaignid AND
a.id = c.applicationid AND
f.accountid = a.accountid