addSql( <<<'SQL' WITH doublons_ordered AS ( SELECT h2.id AS h2id, h2.createdAt AS h2createdAt, h2.startDate AS h2start, h2.endDate AS h2end, h1.*, rank() OVER (partition by h1.period_id ORDER BY h1.id, h2.id) AS ranking FROM chill_person_accompanying_period_location_history h1 JOIN chill_person_accompanying_period_location_history h2 ON h1.period_id = h2.period_id AND h1.id <> h2.id WHERE daterange(h1.startdate, h1.enddate) && daterange(h2.startdate, h2.enddate) ORDER BY h1.period_id, h1.id ), keep_only_first AS ( SELECT id FROM doublons_ordered WHERE ranking > 1 ) DELETE FROM chill_person_accompanying_period_location_history WHERE id IN (SELECT id FROM doublons_ordered); SQL ); $this->addSql( <<<'SQL' ALTER TABLE chill_person_accompanying_period_location_history ADD CONSTRAINT acc_period_location_history_not_overlaps EXCLUDE USING GIST (period_id with =, tsrange(startdate, enddate) with &&) DEFERRABLE INITIALLY DEFERRED SQL ); } public function down(Schema $schema): void { $this->addSql( <<<'SQL' ALTER TABLE chill_person_accompanying_period_location_history DROP CONSTRAINT acc_period_location_history_not_overlaps SQL ); } }