Function PostgreSQL触发器和函数填充的列太多

Function PostgreSQL触发器和函数填充的列太多,function,postgresql,triggers,schema,plpgsql,Function,Postgresql,Triggers,Schema,Plpgsql,我正在为一家大型电子邮件营销公司管理一个提醒消息数据库。我们每天都会提醒用户执行与奖金相关的功能。我为跟踪采集和损耗设置的部分分析需求要求我设置用户订阅和取消订阅的日期。我有一个PostgreSQL触发器,用于触发一个过程,为每个选项更新dateunsub和datejoined列 我的表架构如下所示: 选择加入本身(optinX_unsub)为“Y”、“N”或NULL(是表示用户希望不再接收消息,不是表示他们希望接收消息) 当optin从NULL变为'N'或从'Y'变为'N'时,OptinX_

我正在为一家大型电子邮件营销公司管理一个提醒消息数据库。我们每天都会提醒用户执行与奖金相关的功能。我为跟踪采集和损耗设置的部分分析需求要求我设置用户订阅和取消订阅的日期。我有一个PostgreSQL触发器,用于触发一个过程,为每个选项更新dateunsub和datejoined列

我的表架构如下所示:

选择加入本身(optinX_unsub)为“Y”、“N”或NULL(是表示用户希望不再接收消息,不是表示他们希望接收消息)

当optin从NULL变为'N'或从'Y'变为'N'时,OptinX_datejoined应设置为now()(这意味着他们以前已订阅,但未订阅,但现在需要返回)。当订阅从“N”变为“Y”(再次表示他们不再需要邮件)时,OptinX_dateunsub应设置为now()

当记录最初插入时,Created_on设置为now(),并且它从不更改。Last_modified设置为now(),只要TG_OP='UPDATE'(当表上发生更新时)

这是我的扳机:

    CREATE TRIGGER upd_optins_trigger BEFORE UPDATE ON 
tablename FOR EACH ROW 
EXECUTE PROCEDURE proc_upd()
这是我的功能:

CREATE OR REPLACE FUNCTION public.proc_upd()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
  IF (NEW.optin1_unsub = 'Y') THEN
       NEW.optin1_dateunsub := now();
  ELSIF (NEW.optin1_unsub = 'N' ) THEN
       NEW.optin1_datejoined := now();
  END IF;

  IF (NEW.optin2_unsub = 'Y') THEN
       NEW.optin2_dateunsub := now();
  ELSIF (NEW.optin2_unsub = 'N') THEN
       NEW.optin2_datejoined := now();
  END IF;

  IF (NEW.optin3_unsub = 'Y') THEN
       NEW.optin3_dateunsub := now();
  ELSIF (NEW.optin3_unsub = 'N' ) THEN
       NEW.optin3_datejoined := now();
  END IF;

  IF (NEW.optin4_unsub = 'Y') THEN
       NEW.optin4_dateunsub := now();
  ELSIF (NEW.optin4_unsub = 'N' ) THEN
       NEW.optin4_datejoined := now();
  END IF;

  IF (NEW.optin5_unsub = 'Y') THEN
       NEW.optin5_dateunsub := now();
  ELSIF (NEW.optin5_unsub = 'N' ) THEN
       NEW.optin5_datejoined := now();
  END IF;

  IF (NEW.optin6_unsub = 'Y') THEN
       NEW.optin6_dateunsub := now();
  ELSIF (NEW.optin6_unsub = 'N' ) THEN
       NEW.optin6_datejoined := now();
  END IF;


  NEW.last_modified := now();
  RETURN NEW;

END;

$function$
现在是我的问题。我有一个应用程序,它每天通过CRON为每个opt-in使用这个查询,并将其传递到一个报告API中:

select
count (*) as tablename_total,
(
select
count (*)
from
tablename
where
  optin1_dateunsub = '2014-04-22') as optin1_unsub_yesterday,
  (
select
  count (*)
from
  tablename
where
  optin1_dateunsub between date_trunc('month',
  current_date) and
  '2014-04-22') as optin1_unsub_this_month,
  (
select
  count (*)
from
  tablename
where
  optin1_unsub = 'N' and
  (emailaddress_status = 'VALID' or
  emailaddress_status is null)) as optin1_reminder_total,
  (
select
  count (*)
from
  tablename
where
optin1_unsub = 'N' and
(emailaddress_status = 'VALID' or
emailaddress_status is null) and
optin1_datejoined = '2014-04-22') as optin1_reminder_yesterday,
...
以下是事实发生后的数字

目前,用户有兴趣接收有关optin2、optin5或optin6的电子邮件的唯一“事件”与optin2相关——optin2是最大且促销最多的,因此,optin2的14903个新订阅量与预期一致。与optin1相关的事件早已结束,因此该列表中的11k个新订户和1k个丢失订户很奇怪。optin3也是如此,该事件不会再持续几个月,因此,当我们不向这些订阅者发送邮件时,我们失去了5258份订阅,这似乎是我的触发器和功能的问题。当我们每天向他们发送邮件时,我们不会经常失去那么多订户


对不起,我说的太多了,只是想说得透彻一点。任何帮助都将不胜感激。

您真的应该在这里重新考虑您的模式,您真的不应该重复这样的列。这将大大简化您的触发器。我想我已经将其缩小到新的。*部分。这应该是旧的。*。电子邮件营销人员。。我能想到更糟的。如果是合乎道德的(这意味着订阅者的愿望在任何时候都会得到尊重——在被要求时立即得到尊重——如果营销人员从未向任何人发送邮件,除非明确指出),这是一个非常有价值的营销渠道。我可能是在偷车或者用棍棒打海豹宝宝。。。