Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 查询以检查开始日期和结束日期之间的日期范围(如果postgres中的数据库中已存在)_Sql_Postgresql_Date - Fatal编程技术网

Sql 查询以检查开始日期和结束日期之间的日期范围(如果postgres中的数据库中已存在)

Sql 查询以检查开始日期和结束日期之间的日期范围(如果postgres中的数据库中已存在),sql,postgresql,date,Sql,Postgresql,Date,我必须在两个日期范围内分配机票预订,即从一个可用的开始日期到结束日期,这是以前没有分配的。 为此,我需要在数据库中检查这些日期之间是否已经发生了任何分配 例如,我需要分配2017/04/20至2017/04/25的机票预订。在插入此记录之前,我需要检查在2017/04/20开始日期和2017/04/25结束日期之间是否有以前发生的预订 我尝试了下面的查询,但结果不正确 select "id" from "table" where "from_date" >= '2017-04-20'

我必须在两个日期范围内分配机票预订,即从一个可用的开始日期到结束日期,这是以前没有分配的。 为此,我需要在数据库中检查这些日期之间是否已经发生了任何分配

例如,我需要分配2017/04/20至2017/04/25的机票预订。在插入此记录之前,我需要检查在2017/04/20开始日期和2017/04/25结束日期之间是否有以前发生的预订

我尝试了下面的查询,但结果不正确

select "id" 
from "table" 
where "from_date" >= '2017-04-20' 
  and "to_date" > '2017-04-20' 
  and "from_date" < '2017-04-25' 
  and "to_date" <= '2017-04-25'
使用“重叠”操作符:

select count(*) = 0 as allow_booking
from "table"
where (from_date, to_date) overlaps (date '2017-04-20', date '2017-04-25');
这也将照顾到那些不完全在测试范围内的预订

如果允许预订,查询将返回true,如果不允许,则返回false

示例:

create table bookings 
(
  id serial,
  from_date date, 
  to_date date
);

insert into bookings 
  (from_date, to_date) 
values 
  (date '2017-04-20', date '2017-04-20'),
  (date '2017-04-20', date '2017-04-24'),
  (date '2017-04-26', date '2017-04-29');
接下来

select *
from bookings
where (from_date, to_date) overlaps (date '2017-04-18', date '2017-04-19');
将不返回任何内容,因此count*=0返回true

以下查询:

select *
from bookings
where (from_date, to_date) overlaps (date '2017-04-20', date '2017-04-25');
返回:

id |从|日期|到|日期 --+------+------ 1 | 2017-04-20 | 2017-04-20 2 | 2017-04-20 | 2017-04-24 所以count*=0返回false

以及查询:

select *
from bookings
where (from_date, to_date) overlaps (date '2017-04-27', date '2017-04-28');
将返回:

id |从|日期|到|日期 --+------+------ 3 | 2017-04-26 | 2017-04-29
对于该计数*=0也是错误的。

只是为了检查另一种方式,另一种查询不使用重叠运算符,而只使用And和et或: 使用马发布的数据。。。。这就是逻辑:


TO_DATE>=[您的开始日期]和TO_DATE您的查询没有给出预期的结果,因为您只测试了3种或4种可能的重叠/交叉方式中的1种:

existing date periods:  +--------------+      +-----+       +----+   +-----+
                            contains        contained by        touches
testing periods:            +------+       +------------+     +---------+
要测试每种可能的重叠方式,可以使用的重叠运算符:&&

但请注意:仅使用此类手动检查并不能防止在高并发性中插入重叠的日期范围。在这个测试之后&在实际插入另一个并发语句之前,有一个小窗口用于插入冲突行。为了避免这种情况,您可以使用:

注意:daterange的overlaps操作符&&的工作方式与overlaps操作符相同,由@a_horse_以_no_名称提及。除:

它支持排除约束 它支持使用索引如果添加了排除约束,则会自动为您创建索引 可以微调如何包含范围的边界。默认值为[,意思是:下限是包含的,但上限是独占的。对于重叠,这是唯一支持的包含。 重叠与时区值的时间戳一起使用。您的日期值将被强制转换为该值,使用午夜作为时间&当前时区设置。这可能是您想要的,也可能不是您想要的。
我也遇到了同样的问题。下面的查询将检查数据库中是否存在给定的开始日期或结束日期

$start_date = '2010-01-01';
$end_date = '2017-01-01';

SELECT * FROM `ticket_history` WHERE 
($start_date <= start_date AND $start_date <= end_date AND 
(($end_date >= start_date AND $end_date >= end_date) OR ($end_date >= 
start_date AND $end_date <= end_date))) OR
($start_date >= start_date AND $start_date <= end_date AND 
(($end_date >= start_date AND $end_date >= end_date) OR ($end_date >= 
start_date AND $end_date <= end_date)))

但是我必须允许不在此范围内的预订。在这种情况下,查询不允许works@user2403954:查询将返回属于该范围的ID。因此,如果查询未返回任何内容,则您可以允许预订,如果没有,则必须拒绝预订。您还可以使用计数*来检查,因为您并不真正关心哪些预订存在,仅当我的表格预订中的一个存在仅存在于2017-04-20。现在我尝试使用从2017-04-18到2017-04-19的日期范围。在这种情况下,您所说的预期计数为0,即应该允许在这些日期进行预订分配。但我得到的计数为2。@user2403954:如果您在2017-04-20有预订,那么r 2017-04-1822017-04-19肯定不会返回2:参见此处的示例:已工作..谢谢我认为重叠也可以使用包含两个日期的索引columns@a_horse_with_no_name据我所知,它不能。也许只是索引扫描,但我也不确定。
select count(*)
from   booking
where  daterange(from_date, to_date, '[]') && daterange('2017-04-20', '2017-04-25', '[]');
alter table booking
  add constraint exclude_overlapping_bookings
  exclude using gist (daterange(from_date, to_date, '[]') with &&);
$start_date = '2010-01-01';
$end_date = '2017-01-01';

SELECT * FROM `ticket_history` WHERE 
($start_date <= start_date AND $start_date <= end_date AND 
(($end_date >= start_date AND $end_date >= end_date) OR ($end_date >= 
start_date AND $end_date <= end_date))) OR
($start_date >= start_date AND $start_date <= end_date AND 
(($end_date >= start_date AND $end_date >= end_date) OR ($end_date >= 
start_date AND $end_date <= end_date)))