mysql表的困难约束

mysql表的困难约束,mysql,join,constraints,Mysql,Join,Constraints,我需要一个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.`

我需要一个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`

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

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

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$$
有没有办法用约束来处理这个问题

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

和样本插入:

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;

如果我错了,请纠正我,但我认为您需要一个触发器来处理类似的内容。MySQL约束只检查是否存在,而不检查值范围。使用触发器很容易。然后触发器必须在插入或更新之前停止执行,并可能引发异常,这可能吗?是的,可能。从触发器调用sp1运行未知过程,或者在MySQL 5.5上使用SIGNAL语句
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;