sql >> Database >  >> RDS >> Mysql

Datumbereiken vergelijken

Dit is een klassiek probleem, en het is eigenlijk makkelijker als je de logica omdraait.

Laat me je een voorbeeld geven.

Ik zal hier een tijdsperiode posten, en alle verschillende variaties van andere perioden die elkaar op de een of andere manier overlappen.

           |-------------------|          compare to this one
               |---------|                contained within
           |----------|                   contained within, equal start
                   |-----------|          contained within, equal end
           |-------------------|          contained within, equal start+end
     |------------|                       not fully contained, overlaps start
                   |---------------|      not fully contained, overlaps end
     |-------------------------|          overlaps start, bigger
           |-----------------------|      overlaps end, bigger
     |------------------------------|     overlaps entire period

aan de andere kant, laat me al die dingen posten die elkaar niet overlappen:

           |-------------------|          compare to this one
     |---|                                ends before
                                 |---|    starts after

Dus als je de vergelijking eenvoudig reduceert tot:

starts after end
ends before start

dan vind je al die periodes die elkaar niet overlappen, en dan vind je alle niet-overeenkomende periodes.

Voor je definitieve NOT IN LIST-voorbeeld kun je zien dat het overeenkomt met die twee regels.

U moet beslissen of de volgende periodes IN of BUITEN uw bereik zijn:

           |-------------|
   |-------|                       equal end with start of comparison period
                         |-----|   equal start with end of comparison period

Als uw tabel kolommen heeft met de namen range_end en range_start, volgt hier een eenvoudige SQL om alle overeenkomende rijen op te halen:

SELECT *
FROM periods
WHERE NOT (range_start > @check_period_end
           OR range_end < @check_period_start)

Let op de NIET daarin. Aangezien de twee eenvoudige regels alle niet-overeenkomende rijen, een simpele NOT zal het omkeren om te zeggen:als het niet een van de niet-overeenkomende rijen is, moet het een van de overeenkomende rijen zijn .

Als je hier eenvoudige omkeringslogica toepast om de NIET kwijt te raken, krijg je:

SELECT *
FROM periods
WHERE range_start <= @check_period_end
      AND range_end >= @check_period_start


  1. Verzamelmethode:BESTAAT Functie in Oracle Database

  2. Invoegen in Oracle en ophalen van de gegenereerde sequentie-ID

  3. Retourneer een lijst met alle servertriggers in SQL Server

  4. Alternatief voor het gebruik van het trefwoord LIMIT in een SubQuery in MYSQL