标签: interval

如何检查 PostgreSQL 中是否没有时间间隔?

架构

CREATE TABLE "expenses_commissionrule" (
    "id" serial NOT NULL PRIMARY KEY, 
    "country" varchar(2) NOT NULL, 
    "created" timestamp with time zone NOT NULL, 
    "modified" timestamp with time zone NOT NULL, 
    "activity" tsrange NOT NULL
); 
Run Code Online (Sandbox Code Playgroud)

说明

我想创建一个应用程序来管理佣金计算。每个规则都有活动期。每个国家都有一套独立的规则。

约束

第一的。为避免歧义,这些活动期不应重叠。我做了以下约束:

ALTER TABLE expenses_commissionrule 
ADD CONSTRAINT non_overlapping_activity 
EXCLUDE USING GIST (country WITH =, activity WITH &&);
Run Code Online (Sandbox Code Playgroud)

第二。在任何时间点都应该只有一个佣金规则,因此表中的间隔之间不应存在间隙。换句话说,所有区间的总和应该是 -INF:+INF。

问题:如何添加第二个约束?用例:我们有一个无限期的规则。我想切换到新规则,该规则应从下个月开始。在这种情况下,我想将当前规则结束期设置为当月月底,并在单个操作中添加新规则。

更新:将来我想添加以下行为:

  1. 仅为特定用户指定规则的能力(通过可为空的外键“user_id”);
  2. 每个用户都可以为每个国家/地区制定自己的规则。如果用户没有规则——“全局”规则将用于佣金计算,所以它就像一个后备;
  3. 这些“用户”规则可以有任何活动时间段 - (-inf: inf) 和具体的时间间隔。它与“全局”规则不同——这里的差距是可以的。
  4. 由于“可能是”功能 - 额外的 varchar 字段,这将有一种情况,当可以应用特定规则以在计算过程中具有更大的灵活性时。这个“部分”规则也可能有不同的间隔,间隙是可以的。

换句话说,所有先前的约束都应仅应用于 user_id 为 NULL 的行。如何做到这一点?

PostgreSQL …

postgresql database-design constraint interval

7
推荐指数
1
解决办法
685
查看次数

季度的通用结束日期,PostgreSQL

我想生成给定日期的通用季度结束日期。

例如:如果我有2010-01-01,我想返回2010-03-31,等等。

我可以得到季度号和年份:

select to_char(date_trunc('quarter',  current_date)::date, 'yyyy-q');
Run Code Online (Sandbox Code Playgroud)

2017-3从今天起返回的是2017-07-14

我如何很好地获得季度结束日期?

我可以得到答案,但它非常丑陋:

select to_char(date_trunc('year',  date '2015-01-01'),'yyyy') || '-' ||case
    when (select extract('quarter' from date_trunc('quarter', date '2015-01-01')::date )) = 1 then '03-31'
    when (select extract('quarter' from date_trunc('quarter', date '2015-01-01')::date )) = 2 then '06-30'
    when (select extract('quarter' from date_trunc('quarter', date '2015-01-01')::date )) = 3 then '09-30'
    when (select extract('quarter' from date_trunc('quarter', date '2015-01-01')::date )) = 4 then '12-31'
    else '?'
    end 
Run Code Online (Sandbox Code Playgroud)

返回2015-03-31因为我把2015-01-01

有没有更好的办法?

postgresql functions date interval

7
推荐指数
1
解决办法
8356
查看次数

在参数化查询中传递数据类型区间的值

上下文正在从其余服务器连接到 Postgres 数据库。

考虑一个假设的代表性示例:我希望能够获取帐户创建日期比任意值早/新的名称列表。

在下面的示例查询中,表结构很简单 -name是 type text,并且creation_date是 type timestamp。所以当我做类似的事情时

server_pg_module:query("select name from new_table where 
current_timestamp - creation_date < '6 days'") 
Run Code Online (Sandbox Code Playgroud)

它工作得很好。但我真正想做的是6 days从服务器获取该值。所以我尝试像

server_pg_module:query("select name from new_table where
current_timestamp - timestamp < $1", ["6 days"]
Run Code Online (Sandbox Code Playgroud)

它抛出一个错误。我试过'6 days'"'6 days'"以及其他一些混合物,都抛出错误。所以为了检查我添加了一个新interval的类型列interval并尝试了一个查询

server_pg_module:query("insert into new_table (name, interval) values ($1, '3 day')", ["fooo"]). 
Run Code Online (Sandbox Code Playgroud)

哪个有效,但是

server_pg_module:query("insert into new_table (name, interval) values ($1, $2)", ["fooo", "3 days"]). 
Run Code Online (Sandbox Code Playgroud)

休息。为了更好的衡量,除了"'3 days'"上面提到的混合物之外,我还尝试过 …

postgresql datatypes parameter interval postgresql-10

7
推荐指数
1
解决办法
5437
查看次数

MySQL - 合并或拆分日期时间间隔(开始日期到结束日期)

我有一个表,其中存储了一个活动列表,其时间间隔由 2 个日期分隔。

样本:

+------+---------------------+---------------------+-------------+
| name |        start        |         end         | time (calc) |
+------+---------------------+---------------------+-------------+
|  me  | 2017-04-03 11:00:00 | 2017-04-03 11:30:00 |          30 |
|  me  | 2017-04-03 23:45:00 | 2017-04-04 00:15:00 |          30 |
|  me  | 2017-04-04 10:00:00 | 2017-04-04 11:00:00 |          60 |
|  me  | 2017-04-04 10:30:00 | 2017-04-04 11:30:00 |          60 |
|  me  | 2017-04-05 23:00:00 | 2017-04-05 23:30:00 |          30 |
|  me  | 2017-04-05 23:15:00 | 2017-04-07 00:45:00 | …
Run Code Online (Sandbox Code Playgroud)

mysql datetime interval

6
推荐指数
1
解决办法
1万
查看次数

如何将时间四舍五入到任意时间间隔的上倍数?

例子:

  • 如果当前时间为 2018-05-17 22:45:30 且所需时间间隔为INTERVAL '5 minute',则所需输出为 2018-05-17 22:50:00。
  • 如果当前时间为 2018-05-17 22:45:30 且所需时间间隔为INTERVAL '10 minute',则所需输出为 2018-05-17 22:50:00。
  • 如果当前时间为 2018-05-17 22:45:30 并且所需的时间间隔为INTERVAL '1 hour',则所需的输出为 2018-05-17 23:00:00。
  • 如果当前时间是 2018-05-17 22:45:30 并且期望的间隔是INTERVAL '1 day',那么期望的输出是 2018-05-18 00:00:00。

postgresql datetime interval date-math

5
推荐指数
1
解决办法
3613
查看次数

从起始范围选择所有重叠范围

我的问题与这个问题类似,(我认为)有足够大的差异。我有一个基本范围,我想在一个表中找到所有其他范围与它和彼此冲突。或者更确切地说是形成范围的项目,但它并没有真正产生影响。

带星号的那一行是起始范围。范围 1,2 和 3 是应该扩展它的范围。结果范围应该是 X。

1 | 
3 |    ===1====            ====
5 | ==2==    ====*====           ====
6 |             ====3====     =====          
--+-------------------------------------
  | |<--------X-------->|
Run Code Online (Sandbox Code Playgroud)

我写过这个:

WITH   cte
AS (
    SELECT DATA1.ID, DATA1.STARTDATE, DATA1.ENDDATE
    FROM DATA1
    WHERE 
    DATA1.ID = @PARID AND 
    DATA1.STARTDATE > @STARTDATE AND 
    DATA1.ENDDATE < @ENDDATE 

    UNION ALL

    SELECT DATA1.ID, DATA1.STARTDATE, DATA1.ENDDATE
    FROM cte 
    INNER JOIN DATA1 ON (DATA1.ID = cte.ID)
    WHERE 
    DATA1.ID = @PARID AND 
    (cte.STARTDATE < DATA1.ENDDATE AND cte.ENDDATE > DATA1.ENDDATE)
) …
Run Code Online (Sandbox Code Playgroud)

sql-server query interval

5
推荐指数
1
解决办法
2807
查看次数

计算区间表的集合差

我经常遇到以下问题。我有两张间隔表。它们受日期限制(没有时间部分)。每个表中的间隔不重叠。

开始时间 结束时间
2015-01-03 2015-03-02
2015-03-05 2015-04-01
开始时间 结束时间
2015-01-07 2015-02-27
2015-03-01 2015-03-13
2016-01-01 2016-01-02

我想找到两个表的集合差异,即代表第一个表中而不是第二个表中的时间的间隔。

上面的虚拟示例所需的输出:

开始时间 结束时间
2015-01-03 2015-01-06
2015-02-28 2015-02-28
2015-03-14 2015-04-01

即,如果第一个表的日期在下面用黄色标记,并且第二个表的范围用框包围,我将寻找未装箱的黄色日期的连续范围。

在此输入图像描述

我目前将两端都视为包含间隔,并使用 DateTime 作为时间戳。我当前的方法是通过三重自连接(恶心)获取第二个表的补集,然后通过连接将结果与第一个表相交。不好玩。

有更好的方法吗?

sql-server datetime interval sql-server-2019

5
推荐指数
1
解决办法
357
查看次数

如何使用减去天数的表达式添加生成的列?

我在 PostgreSQL 13 中有这个表:

CREATE TABLE public."domain" (
    id int8 NOT NULL GENERATED ALWAYS AS IDENTITY,
    domain_name varchar NOT NULL,
    -- more columns
    expire_date timestamp NULL,
    days_before_trigger int4 NOT NULL DEFAULT 14
);
Run Code Online (Sandbox Code Playgroud)

现在我想添加一个生成的列notify_trigger_date,派生自expire_datedays_before_trigger,以记录我的网站 url ssl 证书到期日期。如何自动生成该列?
它看起来像这样:

notify_trigger_date = expire_date - 7 day
Run Code Online (Sandbox Code Playgroud)

我正在尝试像这样实现它:

ALTER TABLE "domain" ADD COLUMN notify_trigger_date timestamp 
    GENERATED ALWAYS AS ((expire_date::timestamp - '1 day')) STORED;
Run Code Online (Sandbox Code Playgroud)

我不知道如何1 day用天数替换days_before_trigger?此命令运行时出错:

SQL Error [22007]: ERROR: invalid input syntax for …
Run Code Online (Sandbox Code Playgroud)

postgresql database-design computed-column interval

3
推荐指数
2
解决办法
305
查看次数