OVERLAPS 运算符检查多个行

OVERLAPS operator to check multiples rows

目前我正在使用重叠运算符,这样用户就无法插入重叠的日期。我创建了这个函数:

    CREATE OR REPLACE FUNCTION overlap(docent_medewerkerscode1 CHARACTER(7),  
lokaal1 TEXT, groep_groepsnaam1 TEXT, startdatum1 timestamp, einddatum1 
timestamp)

RETURNS TEXT AS $$
DECLARE
    resultaat TEXT;
    rec rooster%rowtype;
BEGIN 
    FOR rec IN SELECT groep_groepsnaam = groep_groepsnaam1 OR lokaal =      
lokaal1 OR docent_medewerkerscode = docent_medewerkerscode1 FROM rooster 
  LOOP
        IF(startdatum1, einddatum1) OVERLAPS (startdatum, einddatum) FROM  
rooster THEN
           --IF startdatum1 BETWEEN startdatum AND einddatum AND einddatum1 BETWEEN startdatum AND einddatum FROM rooster THEN
            resultaat = 'tijd overlapt';
            RAISE 'Niet mogelijk tijd komt overeen met ingeplande tijd';
        END IF;
  END LOOP;

RETURN resultaat;
END;
$$ LANGUAGE plpgsql;

问题是重叠不适用于多行。

(ERROR: query "SELECT (startdatum1, einddatum1) OVERLAPS (startdatum, einddatum) FROM rooster" returned more than one row)

我正在寻找一种方法,让重叠检查 select 查询中的每一行。你们中有人知道我能做什么吗?

错误消息的直接原因是 plpgsql IF statement 需要一个 单个 布尔表达式,而您的代码 returns 一整套布尔表达式.

IF(startdatum1, einddatum1) OVERLAPS (startdatum, einddatum) FROM  
rooster THEN

是以下的丑陋缩写形式:

IF (SELECT(startdatum1, einddatum1) OVERLAPS (startdatum, einddatum)
    FROM  rooster) THEN

而且这种方式根本无效。您必须汇总或使用 EXISTS:

IF EXISTS (
   SELECT 1 FROM  rooster r
   WHERE  (startdatum1, einddatum1) OVERLAPS (r.startdatum, r.einddatum)
   ) THEN ...

更重要的是,exclusion constraint 几乎肯定是您问题的更好解决方案(需要 Postgres 9.0+):

  • Postgres constraint for unique datetime range
  • Preventing adjacent/overlapping entries with EXCLUDE in PostgreSQL