gpt4 book ai didi

django - Django 中的 Pgsql 重叠函数

转载 作者:行者123 更新时间:2023-11-29 12:35:01 25 4
gpt4 key购买 nike

我正在开发一个项目,我需要根据开始日期和结束日期从表中提取日期。这是查询

SELECT *  FROM billing_lines  WHERE (start_date, end_date) OVERLAPS ('2018-09-15 03:00:00', '2018-09-15 03:30:00');

我知道我可以使用raw()来执行上述查询。但我的问题是,如何将其转换为 Django ORM 查询。

最佳答案

两个范围[a1, b1)[a2, b< sub>2)如果a1≥b2,则重叠,或b1≤a2。我们可以否定这个表达式来知道两个间隔何时重叠:a1 2 b1 sub>>a2

这里start_dateend_date分别是 a1b1,你写的两个值 '2018-09-15 03:00:00''2018-09-15 03:30:00'因此分别是 a2b2

因此我们可以进行如下查询:

begin='2018-09-15 03:00:00'
end='2018-09-15 03:30:00'

Lines.objects.filter(
start_date__lt=end
end_date__gt=begin
)

因此,这不会检查 (begin, end) 是否被“包含”在(start_date, end_date)中,它检查是否至少有一个元素同时属于两个范围。

现在是 OVERLAP function in PostgreSQL有点复杂,因为它会自动交换时间,以防 end_date大于start_date ,所以我们可能需要使用 .annotate(..)这里:

from django.db.models import F
from django.db.models.functions import Greatest, Least

begin='2018-09-15 03:00:00'
end='2018-09-15 03:30:00'

Lines.objects.annotate(
d0=Least(F('start_date'), F('end_date')),
d1=Greatest(F('start_date'), F('end_date')),
).filter(
d0__lt=end
d1__gt=begin
)

这仍然不完全相同,因为 if d0d1相同,那么范围是“包含”的,所以我们也应该考虑这种情况:

Lines.objects.annotate(
d0=Least(F('start_date'), F('end_date')),
d1=Greatest(F('start_date'), F('end_date')),
).filter(
Q(d0__lt=end, d1__gt=begin) |
Q(d0=F('d1'), d0__gte=begin, d0__lt=end)
)

还需要“准备”beginend (您应该确保 begin <= end ,如果不交换它们,不是因为否则该方法将失败,而是因为这些是相当复杂的 OVERLAP 函数的“精确”规范)。

关于django - Django 中的 Pgsql 重叠函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52855885/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com