postgresql

时间:2016-07-20 06:37:56

标签: database postgresql function

我正在研究这两个表bats.batches和courses.course_teacher在课程表中我有courseid batch_id和trainer_id ...所以现在我的要求是我要检查批次是否有课程,而不是我必须检查所有课程必须至少有一个培训师为所有课程。我现在为您提供我的旧功能,只有检查批次有培训师...但我想要批量检查所有课程必须有培训师。如果有一个培训师的所有课程 比返回1还有0 ...

课程表

CREATE TABLE courses.course_teacher (
id SERIAL,
courseid INTEGER NOT NULL,
is_deleted BOOLEAN DEFAULT false,
trainer_id INTEGER[],
batch_id INTEGER,
qp_id INTEGER,
pedagogy_session TIMESTAMP WITH TIME ZONE,
assignedby INTEGER,
CONSTRAINT course_teacher_pkey PRIMARY KEY(id),
CONSTRAINT course_teacher_fk FOREIGN KEY (courseid)
REFERENCES courses.courses(id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE
) 
WITH (oids = false);

CREATE INDEX inx_courses_course_teacher_batch_id ON            courses.course_teacher
USING btree (batch_id);

CREATE INDEX inx_courses_course_teacher_course_id ON     courses.course_teacher
USING btree (courseid);

 CREATE INDEX inx_courses_course_teacher_trainer_id ON courses.course_teacher
 USING btree (trainer_id);

我的旧功能.............

DECLARE
d_trainerids INTEGER[];
BEGIN
-- Below query for active trainers only..
select array_agg(ua.id) into d_trainerids   
    from batches.batches bb 
    LEFT JOIN center.center cc on bb.centre_id = cc.id
    LEFT JOIN programs.program_courses ppc on bb.program_id =      ppc.program_id
    LEFT JOIN courses.course_teacher cct on cct.courseid::text = ANY(ppc.course_ids)
    LEFT JOIN users.accounts ua on ua.id = ANY(cct.trainer_id)
    where bb.centre_id = i_centerid --and bb.end_date::date >= now()::date 
    and bb.is_deleted = FALSE and bb.is_active = TRUE and cct.trainer_id <> '{}' and ua.status = 1;

return query
select b.id, b.batch_name, b.batch_code, --count(ud.id)::INTEGER,

(select count(ud.id) from users.userdetail ud LEFT JOIN users.roles ur on ur.user_id = ud.userid
    where b.id = ANY(ud.batch_id))::INTEGER, --and ud.centre_id = i_centerid and 2 = ANY(ur.roles))::INTEGER,

(select center_name from center.center where id = i_centerid and is_active = true and is_deleted = false),

(select id from center.center where id = i_centerid and is_active = true and is_deleted = false), pp.name,

to_char(b.start_date,'dd/mm/yyyy'), pp.id, to_char(b.end_date, 'dd/mm/yyyy'),
case        when b.status = '1' THEN 'Ongoing'::text
              when b.status = '2' THEN 'Closed'::text
              when b.status = '3' THEN 'Cancelled'::text
              when b.status = '4' then 'Open'::text
              when b.status = '5' then 'Closed & Billed'::text END,

case when b.actualregistration = null then '0'
     WHEN b.actualregistration::text = ' ' then '0' 
     else b.actualregistration::text end,
     --case for checking trainer in a batch
case when (d_trainerids @> (select array_unique(array_agg(ua.id))
        from courses.course_teacher cct 
        left join users.accounts ua on ua.id = ANY(cct.trainer_id) and ua.status <> 0
        where b.id = cct.batch_id and cct.trainer_id <> '{}' and ua.status <> 0)) = TRUE THEN 1::INTEGER ELSE 0::INTEGER END,

case when b.end_date::date >= now()::date then 'Open' else 'Close' END, 0

from batches.batches b
--LEFT join users.userdetail ud on b.id = ANY(ud.batch_id)
--LEFT JOIN users.roles ur on ur.user_id = ud.userid
LEFT JOIN programs.programs pp on b.program_id = pp.id
LEFT JOIN programs.program_courses ppc on pp.id = ppc.program_id
where b.centre_id = i_centerid and b.is_active = true and b.is_deleted = false ORDER by b.start_date DESC; --and b.end_date::date >= now()::date 
--GROUP by b.id, b.batch_name, b.batch_code, pp.name, b.start_date, pp.id, ppc.course_ids;
END;

这是一个较旧的案例

 --case for checking trainer in a batch
case when (d_trainerids @> (select array_unique(array_agg(ua.id))
        from courses.course_teacher cct 
        left join users.accounts ua on ua.id = ANY(cct.trainer_id) and ua.status <> 0
        where b.id = cct.batch_id and cct.trainer_id <> '{}' and ua.status <> 0)) = TRUE THEN 1::INTEGER ELSE 0::INTEGER END,

以上代码检查批次中的情况如果我有一个批处理培训师然后它将返回我1其他0 ....但问题是批处理可以有多个课程。所以我想改变这个案例为检查每个课程的培训师....所以我只是为检查条件设置一个foreach循环

(foreach cctcourse in ARRAY cct.courseid loop 
            if cctcourse is not null THEN
            cct.trainer_id<>'{}' and ua.status <> 0
            end if;
            end loop;) )) = TRUE THEN 1::INTEGER ELSE 0::INTEGER END,

但添加此内容后出现错误语法错误,我将此代码替换为原始

     case when (d_trainerids @> (select array_unique(array_agg(ua.id))
        from courses.course_teacher cct 
        left join users.accounts ua on ua.id = ANY(cct.trainer_id) and ua.status <> 0
        where   (foreach cctcourse in ARRAY cct.courseid loop 
                if cctcourse is not null THEN
                cct.trainer_id<>'{}' and ua.status <> 0
                end if;
                end loop;) )) = TRUE THEN 1::INTEGER ELSE 0::INTEGER END,

在上面的代码中我收到错误

  

错误:“cctcourse”或附近的语法错误   第44行:在哪里(在ARRAY cct.courseid的前期cctcourse ...

我只是从cct.courseid获取所有值并存储在变量cctcourse中,但是当我想要执行此操作时,它会显示我的错误,我错了?我怎么能解决这个问题...

0 个答案:

没有答案