2016-05-17 4 views
1

Я хочу, чтобы проверить в MySQL, если цепочка дат существует больше, чем 5. Например:проверка MYSQL, если цепь дат существует

11-05-2016 
12-05-2016 
13-05-2016 
14-05-2016 
15-05-2016 

Эти строки были бы в моей БД, это было бы цепь из 5. Я хочу, чтобы триггер на столе, чтобы защитить свои данные от создания сети больше, чем 5.

+0

Ваша проблема в вашем подходе. MySQL полагается на реляционную модель. Эти даты должны быть в отдельных строках, связанных с другой таблицей через внешние ключи. Затем вы можете спросить себя о ограничениях, которые вы добавляете в свою схему. –

+0

Что делать, если 16-го и 17-го присутствуют, но отсутствует 13-й? Не могли бы вы вставить «13»? – Strawberry

+0

@ HéctorValverdePareja Ухаживать за разработкой? – Strawberry

ответ

0

Вот неполный ответ ...

Я не претендующее это довольно (и весов плохо тоже), но это, по крайней мере, демонстрирует принцип, который другие могли бы построить ...

DROP TABLE IF EXISTS my_table; 

CREATE TABLE my_table(dt DATE NOT NULL PRIMARY KEY); 

INSERT INTO my_table VALUES 
('2016-05-01'), 
('2016-05-02'), 
('2016-05-03'), 
('2016-05-05'), 
('2016-05-07'), 
('2016-05-08'), 
('2016-05-09'), 
('2016-05-11'), 
('2016-05-12'), 
('2016-05-13'), 
('2016-05-14'); 

Здесь мы имеем полосу 3-х дней (с 1 по 3), после чего полоса 1 день (5), а затем еще на полосу 3-х дней (7 по 9), а затем в 4 дня полоса (с 11 по 14).

Итак, мы должны иметь возможность вставить значение '2016-05-15' (потому что это приведет к 5-дневной полосе), но не '2016-05-10' (потому что это сделало бы 8 дневная полоса).

1. 2016-05-10

SET @x = '2016-05-10'; 

SELECT a.dt start 
    , MIN(c.dt) end 
    FROM 
    (SELECT dt FROM my_table 
     UNION 
     SELECT @x 
    ) a 
    LEFT 
    JOIN 
    (SELECT dt FROM my_table 
     UNION 
     SELECT @x 
    ) b 
    ON b.dt = a.dt - INTERVAL 1 DAY 
    LEFT 
    JOIN 
    (SELECT dt FROM my_table 
     UNION 
     SELECT @x 
    ) c 
    ON c.dt >= a.dt 
    LEFT 
    JOIN 
    (SELECT dt FROM my_table  
     UNION 
     SELECT @x 
    ) d 
    ON d.dt = c.dt + INTERVAL 1 DAY 
WHERE b.dt IS NULL 
    AND c.dt IS NOT NULL 
    AND d.dt IS NULL 
GROUP 
    BY a.dt 
HAVING DATEDIFF(end,start)>5; 

+------------+------------+ 
| start  | end  | 
+------------+------------+ 
| 2016-05-07 | 2016-05-15 | 
+------------+------------+ 

2. 2016-05-15

SET @x = '2016-05-15'; 

SELECT a.dt start 
    , MIN(c.dt) end 
    FROM 
    (SELECT dt FROM my_table 
     UNION 
     SELECT @x 
    ) a 
    LEFT 
    JOIN 
    (SELECT dt FROM my_table 
     UNION 
     SELECT @x 
    ) b 
    ON b.dt = a.dt - INTERVAL 1 DAY 
    LEFT 
    JOIN 
    (SELECT dt FROM my_table 
     UNION 
     SELECT @x 
    ) c 
    ON c.dt >= a.dt 
    LEFT 
    JOIN 
    (SELECT dt FROM my_table  
     UNION 
     SELECT @x 
    ) d 
    ON d.dt = c.dt + INTERVAL 1 DAY 
WHERE b.dt IS NULL 
    AND c.dt IS NOT NULL 
    AND d.dt IS NULL 
GROUP 
    BY a.dt 
HAVING DATEDIFF(end,start)>5; 

Empty set (0.03 sec) 
Смежные вопросы