2016-06-29 11 views
8

Lo scenario è il sistema DEMO001 prenotato dal 10 agosto all'11 agosto dall'utente.Scenario per consentire l'aggiornamento basato su booking-SQL

START_DATE  END DATE SYSTEM 
2016-08-10  2016-08-11 DEMO001 
2016-09-05  2016-09-08 DEMO001 
2016-08-08  2016-08-11 DEMO013 
2016-08-16  2016-08-18 DEMO017 

dire se ottengo un parametro di input

1) start date as 2016-08-08 and end date as 2016-08-11 I can allow 
2) start date as 2016-08-11 and end date as 2016-09-08 I cannot allow 
3) start date as 2016-08-10 and end date as 2016-08-15 I can allow 
3) start date as 2016-08-10 and end date as 2016-09-06 I cannot allow 

Se l'utente tenta di aggiornare qualsiasi di questo sistema, estendendo o preponing la data di inizio o di fine, se non altri prenotati tra questi giorni avrò per dire 0 o 1.

Questa è l'estensione di questo scenario

Checking if the "system" falls between two dates in SQL

Ho provato a modificarlo il suggerimento dato lì, ma non è in grado di farlo in modo corretto. Si prega di suggerire.

+0

Forse le risposte alla tua domanda iniziale aiuto a tutti? –

+0

Sì, il suggerimento fornito da @ MT0 viene elaborato – MKN

+0

Quale problema si verifica quando lo si prova? Puoi spiegare di più? – SriniV

risposta

2

Se ho compreso correttamente la tua domanda, stai cercando una soluzione generica per distinguere se i periodi per una risorsa si sovrappongono nel tempo.

Assumendo queste prime quattro righe di esempio sono colonne di una tabella denominata PRENOTAZIONE, e si vuole testare una nuova data per la prima prenotazione, è possibile farlo con le query di questo tipo:

CREATE TABLE booking(system_name VARCHAR2(10) 
        , start_date DATE 
        , end_date  DATE 
        ); 

INSERT INTO booking(system_name, start_date, end_date) 
     VALUES ('DEMO001' 
       , TO_DATE('2016-09-05', 'YYYY-MM-DD') 
       , TO_DATE('2016-09-08', 'YYYY-MM-DD') 
       ); 
-- You only need this record, as you need to filter on the system name anyway 
COMMIT; 

SELECT CASE COUNT(1) WHEN 0 THEN 'I can allow' ELSE 'I cannot allow' END 
      AS outcome 
    FROM DUAL 
WHERE EXISTS 
      (SELECT 1 
       FROM booking old 
      WHERE old.system_name = 'DEMO001' 
       AND old.end_date > TO_DATE('2016-08-08', 'YYYY-MM-DD') 
       AND old.start_date < TO_DATE('2016-08-08', 'YYYY-MM-DD')); 

SELECT CASE COUNT(1) WHEN 0 THEN 'I can allow' ELSE 'I cannot allow' END 
      AS outcome 
    FROM DUAL 
WHERE EXISTS 
      (SELECT 1 
       FROM booking old 
      WHERE old.system_name = 'DEMO001' 
       AND old.end_date > TO_DATE('2016-08-11', 'YYYY-MM-DD') 
       AND old.start_date < TO_DATE('2016-09-08', 'YYYY-MM-DD')); 

SELECT CASE COUNT(1) WHEN 0 THEN 'I can allow' ELSE 'I cannot allow' END 
      AS outcome 
    FROM DUAL 
WHERE EXISTS 
      (SELECT 1 
       FROM booking old 
      WHERE old.system_name = 'DEMO001' 
       AND old.end_date > TO_DATE('2016-08-10', 'YYYY-MM-DD') 
       AND old.start_date < TO_DATE('2016-08-15', 'YYYY-MM-DD')); 

SELECT CASE COUNT(1) WHEN 0 THEN 'I can allow' ELSE 'I cannot allow' END 
      AS outcome 
    FROM DUAL 
WHERE EXISTS 
      (SELECT 1 
       FROM booking old 
      WHERE old.system_name = 'DEMO001' 
       AND old.end_date > TO_DATE('2016-08-10', 'YYYY-MM-DD') 
       AND old.start_date < TO_DATE('2016-09-06', 'YYYY-MM-DD')); 

Naturalmente il La dichiarazione CASE è lì per rendere visivamente chiaro il risultato del test. Se si desidera 0 e 1 per i risultati opposti, basta fare un "non esiste"

4

Prova:

WITH dates AS (

    -- input data (ranges) 
    SELECT date '2016-08-08' as start_date, date '2016-08-11' as end_date from dual union all 
    SELECT date '2016-08-11', date '2016-09-08' from dual union all 
    SELECT date '2016-08-10', date '2016-08-15' from dual union all 
    SELECT date '2016-08-10', date '2016-09-06' from dual 
) 

-- the query 
SELECT d.start_date, d.end_date, 
     CASE WHEN count(*) > 1 
      THEN 'Disallow' ELSE 'Allow' 
      -- change the above line to => THEN 0 ELSE 1 <= if you prefer numbers 
     END is_allowed 
FROM dates d 
LEFT JOIN table1 t1 -- table1 holds booking data, eg DEMO0001 etc. 
ON (d.Start_date <= t1.end_date) and (d.end_date >= t1.start_date) 
    AND t1.system = 'DEMO001' 
GROUP BY d.start_date, d.end_date 
ORDER BY 1 
+0

+1 e hai appena utilizzato la tua risposta per andare in linea con la risposta dell'MTO sull'altro biglietto, in modo che OP lo capisca più facilmente – SriniV

2

Secondo la mia comprensione, è necessario aggiornare le date di prenotazione del sistema esistente solo se nessun altro scontri della data.

Si prega di provare sotto il codice, può funzionare da voi.

CREATE TABLE bookings (BookingId INT IDENTITY(1,1), StartDate Date, EndDate DATE, [SYSTEM] varchar(64)); 

    INSERT INTO bookings (StartDate, EndDate, [SYSTEM]) 
    VALUES 
     ('2016-08-10', '2016-08-11', 'DEMO001'), 
     ('2016-09-05', '2016-09-08', 'DEMO001'), 
     ('2016-08-08', '2016-08-11', 'DEMO013'), 
     ('2016-08-16', '2016-08-18', 'DEMO017'); 

Booking Table

DECLARE 
     @ExistingBookingId INT = 1 
     ,@NewStartDate DATE = '2016-08-10' 
     ,@NewEndDate DATE = '2016-09-06'; 

    DECLARE @SystemCorrespondingToBookingId VARCHAR(64); 

    SELECT @SystemCorrespondingToBookingId = [System] 
    FROM bookings 
    WHERE bookingId = @ExistingBookingId 

    ;WITH AnotherBookingDatesOfSystem (StartDt, EndDt) 
    AS 
    (
     SELECT StartDate, EndDate 
     FROM Bookings 
     WHERE [System] = @SystemCorrespondingToBookingId 
      AND BookingId <> @ExistingBookingId 
    ) 

    SELECT ISNULL(MIN(
      CASE 
      WHEN @NewEndDate < StartDt OR @NewStartDate > EndDt 
      THEN 1 
      ELSE 0 
      END 
      ), 1) AS can_book 
    FROM AnotherBookingDatesOfSystem 

Funziona per tutti determinati scenari.

1

si potrebbe provare questo sulla base della dichiarazione di sql suggerito a voi di cui nel collegamento OP:

SELECT system, min(can_book) can_book 
FROM (
     SELECT system, 
     CASE 
     WHEN (NOT(start_date BETWEEN :start_Date AND :end_date) 
       AND NOT(end_date BETWEEN :start_Date AND :end_date)) 
     THEN 1 
     ELSE 0 
     END 
     ) AS can_book 
FROM table_name 
)GROUP BY system; 
2

credito completo a @kordirko qui, ma solo per farvi capire con il vostro modello di uscita familiare (come dato da @MTO)

Prenotazioni tavolo:

CREATE TABLE table_name (START_DATE, END_DATE, SYSTEMS) AS 
SELECT DATE '2016-08-10', DATE '2016-08-11', 'DEMO001' FROM DUAL UNION ALL 
SELECT DATE '2016-09-05', DATE '2016-09-08', 'DEMO001' FROM DUAL UNION ALL 
SELECT DATE '2016-08-08', DATE '2016-08-11', 'DEMO013' FROM DUAL UNION ALL 
SELECT DATE '2016-08-16', DATE '2016-08-18', 'DEMO017' FROM DUAL; 

query con sistemi variabili bind, data_iniziale, data_finale

SELECT :systems, :start_date, :end_date, 
     CASE WHEN COUNT(*) > 1 
      THEN 'I cannot Allow' ELSE 'I can Allow' 
     END result 
FROM bookings t1 
WHERE (:start_date <= t1.end_date) AND (:end_date >= t1.start_date) 
    AND t1.systems = :systems 
GROUP BY :start_date, :end_date; 

uscita:

1) DEMO001 2016-08-08 2016-08-11 -> I can Allow 
2) DEMO001 2016-08-11 2016-09-08 -> I cannot Allow 
3) DEMO001 2016-08-10 2016-08-15 -> I can Allow 
4) DEMO001 2016-08-10 2016-09-06 -> I cannot Allow