PostgreSQL:基于另一个间接引用的表

时间:2018-02-22 10:27:23

标签: postgresql database-migration

将新列new_column添加到现有表rules后,我想应用一些复杂的迁移逻辑来确定每行的新值(我需要查看另一个表)名为flags,由rules间接引用。

我的问题:

Q1。我可以使用JOINCASE语句完成此操作,还是需要编写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'

2 个答案:

答案 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;

在线示例:http://rextester.com/JHHP6967

答案 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