Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL-Buchungsverfügbarkeit, sich überschneidende Datumsbereiche

  1. Erstellen Sie eine Liste aller Buchungsgrenzen (d. h. Start- und Enddaten), die im gewünschten Zeitraum liegen:

      SELECT date_start AS boundary
      FROM   bookings
      WHERE  date_start BETWEEN @start AND @end
    UNION
      SELECT date_end
      FROM   bookings
      WHERE  date_end BETWEEN @start AND @end
    
  2. Fügen Sie dazu die Grenze hinzu, die unmittelbar vor dem gewünschten Zeitraum liegt:

    -- [ from part 1 above ]
    UNION
      SELECT MAX(boundary)
      FROM (
        SELECT MAX(date_start) AS boundary
        FROM   bookings
        WHERE  date_start <= @start
      UNION ALL
        SELECT MAX(date_end)
        FROM   bookings
        WHERE  date_end <= @end
      ) t
    
  3. Erstellen Sie eine äußere Verknüpfung zwischen diesem Ergebnis und den bookings Tabelle, wobei alle Grenzen eingehalten werden, aber nur dann eine Buchung aufgenommen wird, wenn dies zur Anzahl der gleichzeitigen Personen nach beiträgt die Grenze:

    FROM bookings RIGHT JOIN (
      -- [ from part 2 above ]
    ) t ON date_start <= boundary AND boundary < date_end
    
  4. Summieren Sie die Anzahl der Personen an jeder Grenze:

    SELECT IFNULL(SUM(quantity),0) AS simultaneous_people
    -- [ from part 3 above ]
    GROUP BY boundary
    
  5. Finden Sie das Maximum und Minimum:

    SELECT MIN(simultaneous_people),
           MAX(simultaneous_people)
    FROM (
      -- [ from part 4 above ]
    ) t
    

Alles zusammen:

SELECT MIN(simultaneous_people),
       MAX(simultaneous_people)
FROM (
  SELECT IFNULL(SUM(quantity),0) AS simultaneous_people
  FROM   bookings RIGHT JOIN (
    SELECT date_start AS boundary
    FROM   bookings
    WHERE  date_start BETWEEN @start AND @end
  UNION
    SELECT date_end
    FROM   bookings
    WHERE  date_end BETWEEN @start AND @end
  UNION
    SELECT MAX(boundary)
    FROM (
      SELECT MAX(date_start) AS boundary
      FROM   bookings
      WHERE  date_start <= @start
    UNION ALL
      SELECT MAX(date_end)
      FROM   bookings
      WHERE  date_end <= @end
    ) t
  ) t ON date_start <= boundary AND boundary < date_end
  GROUP BY boundary
) t

Sehen Sie es auf sqlfiddle .