场景为用户预订DEMO001系统的时间为8月10日至8月11日。
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假设我得到了一个输入参数
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如果用户试图通过延长或提前开始或结束日期来更新此系统中的任何一个,如果在这两天之间没有其他人预订,我将不得不说0或1。
这是此场景的扩展
Checking if the "system" falls between two dates in SQL
我试着修改它给出的建议,但不能得到正确的。敬请指教。
发布于 2016-07-02 00:16:40
尝试:
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发布于 2016-07-01 19:31:36
如果我正确理解了您的问题,您正在寻找一种通用的解决方案来区分资源的周期是否在时间上重叠。
假设前四个示例行是名为BOOKING的表中的列,并且您想要测试第一次预订的新日期,您可以使用如下查询来执行此操作:
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' ));当然,CASE语句只是为了使测试结果在视觉上清晰。如果你想用0和1来表示相反的结果,那就把它设为“不存在”。
发布于 2016-07-03 18:39:09
根据我的理解,只有在没有其他日期冲突的情况下,您才需要更新系统的现有预订日期。
请尝试下面的代码,希望它能从你那里工作。
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');

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它适用于所有给定的场景。
https://stackoverflow.com/questions/38090387
复制相似问题