0

我需要一个 mysql 表的约束。该表具有字段“id”、“ref”、“from”和“to”。约束应该保证不存在具有相同“ref”和时间重叠(字段“from”和“to”)的数据集。

在 sql 中:以下语句应始终返回“0”。

select count(*) 
from   `TABLE` d1 inner join `TABLE` d2 on 
       d1.`ref` = d2.`ref` and d1.`id` <> d2.`id` and 
       d1.`to` >= d2.`from` and d1.`from`<=d2.`to`

有没有办法通过约束来处理这个问题?

4

2 回答 2

0

现在我有以下触发器。谢谢你的帮助!

DELIMITER $$

USE `devtestplandb`$$

CREATE
TRIGGER `db`.`trig1`
BEFORE INSERT ON `db`.`TABLE`
FOR EACH ROW
BEGIN
    SET @CNT = (
            select  count(*) 
            from    `TABLE` d 
            where   d.`ref` = NEW.`ref` and 
                    d.`to` >= NEW.`from` and 
                    d.`from` <= NEW.`to`);
    IF @CNT != 0 THEN
        CALL error_001();
    END IF;
END$$

CREATE
TRIGGER `db`.`trig2`
BEFORE UPDATE ON `db`.`TABLE`
FOR EACH ROW
BEGIN
    SET @CNT = (
            select  count(*) 
            from    `TABLE` d 
            where   d.`ref` = NEW.`ref` and 
                    d.`ID` <> NEW.`ID` and
                    d.`to` >= NEW.`from` and 
                    d.`from` <= NEW.`to`);
    IF @CNT != 0 THEN
        CALL error_002();
    END IF;
END$$
于 2012-05-14T10:29:23.447 回答
0

“有没有办法通过约束来处理这个问题?”

是的,SQL Standard 2011 以可读的声明方式支持这种场景:

唯一约束定义

<without overlap specification> ::=
<application time period name>  WITHOUT OVERLAPS

在您的示例中:

CREATE TABLE tab (
  id INT AUTO_INCREMENT PRIMARY KEY,
  ref VARCHAR(100),
  from_date DATE,
  end_date DATE,
  PERIOD FOR ref_period(from_date, end_date),
  UNIQUE (ref, ref_period WITHOUT OVERLAPS)
);

和样本插入:

INSERT INTO tab(ref, from_date, end_date) VALUES ('a', '2020-01-01','2020-03-01');
-- OK

INSERT INTO tab(ref, from_date, end_date) VALUES ('a', '2020-03-01','2020-05-01');
-- OK

INSERT INTO tab(ref, from_date, end_date) VALUES ('a', '2020-04-01','2020-07-01')
-- Duplicate entry 'a-2020-07-01-2020-04-01' for key 'ref

SELECT * FROM tab;

db<>fiddle 演示 - Maria DB 10.5

于 2020-06-25T19:28:48.857 回答