2016-06-29 64 views
8

Scenariusz to system DEMO001 rezerwowany od 10 sierpnia do 11 sierpnia przez użytkownika.Scenariusz umożliwiający aktualizację na podstawie rezerwacji-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 

powiedzieć, czy mam parametr wejściowy

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 

Jeśli użytkownik próbuje zaktualizować każdy tego systemu poprzez rozszerzenie lub preponing datę rozpoczęcia lub zakończenia, jeśli żadne inne zarezerwowane między tymi dni będę mieć powiedzieć 0 lub 1.

Jest to rozszerzenie do tego scenariusza

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

Próbowałem modyfikacji sugestię podane tam, ale nie jest w stanie uzyskać go poprawnie. Uprzejmie sugeruję.

+0

Czy odpowiedź do oryginalnego zapytania pomocy w ogóle? –

+0

Tak, sugestia podana przez @ MT0 została wykonana – MKN

+0

Z jakim problemem napotykasz się podczas próby? Czy możesz wyjaśnić więcej? – SriniV

Odpowiedz

2

Jeśli dobrze rozumiem twoje pytanie, szukasz ogólnego rozwiązania pozwalającego rozróżnić, czy okresy na zasoby nakładają się w czasie.

Zakładając te pierwsze cztery przykładowe linie są kolumny w tabeli o nazwie rezerwacji, a chcesz przetestować nową datę pierwszego rezerwacji, można to zrobić z zapytaniami, jak to:

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')); 

oczywiście Oświadczenie CASE jest po to, aby wynik testu był wizualnie jasny. Jeśli chcesz, 0 i 1 dla przeciwnych efektów, po prostu sprawiają, że „nie istnieje”

4

Spróbuj:

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 i właśnie wykorzystałem twoją odpowiedź, aby dopasować się do odpowiedzi MTO na drugim bilecie, więc OP rozumie to łatwiej – SriniV

2

Według mojego rozeznania, trzeba zaktualizować istniejący termin rezerwacji z systemu tylko wtedy, gdy żadna inna zderzenia daty.

Proszę spróbować poniżej kodu, Niech działa od Ciebie.

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 

To działa dla wszystkich podanych scenariuszach.

1

można spróbować to na podstawie instrukcji SQL zasugerował do was, o których mowa w linku 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

pełny kredyt @kordirko tutaj, ale tylko, aby zrozumieć, z dobrze znanego modelu wyjściowego (jak podano przez @MTO)

rezerwacji stolika:

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; 

Zapytanie z systemem zmiennych zaciągania datą_początkową, datakon

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; 

wyjściowa:

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