加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

PostgreSQL SELECT必须匹配多行

发布时间:2020-12-13 15:57:39 所属栏目:百科 来源:网络整理
导读:我有一个表,其中包含一对表示时间跨度的时间戳.这些行的范围是用户标识,每个用户可以有一个或多个与之关联的行. 此数据是从抽象的“可用性”表单生成的,该表单表示用户何时在一周内可用.我需要输入一系列时间范围作为查询,并返回表中所有行匹配的所有用户ID.
我有一个表,其中包含一对表示时间跨度的时间戳.这些行的范围是用户标识,每个用户可以有一个或多个与之关联的行.

此数据是从抽象的“可用性”表单生成的,该表单表示用户何时在一周内可用.我需要输入一系列时间范围作为查询,并返回表中所有行匹配的所有用户ID.

鉴于此表:

CREATE TABLE "public"."availability" (
  "id" int4 NOT NULL,"user_id" int4,"starts_at" timestamp(6),"ends_at" timestamp(6),PRIMARY KEY ("id")
) WITH (OIDS=FALSE)

而这个数据:

User #1 is available Mon-Tue between 08:00 and 17:00

+----+---------+---------------------+---------------------+
| id | user_id | starts_at           | ends_at             |
+----+---------+---------------------+---------------------+
| 1  | 1       | 2013-03-18 08:00:00 | 2013-03-18 17:00:00 |
+----+---------+---------------------+---------------------+
| 2  | 1       | 2013-03-19 08:00:00 | 2013-03-19 17:00:00 |
+----+---------+---------------------+---------------------+

User #2 is available Sun-Sat all day

+----+---------+---------------------+---------------------+
| 3  | 2       | 2013-03-17 00:00:00 | 2013-03-23 23:59:59 |
+----+---------+---------------------+---------------------+

User #3 is available Wed between 06:00 and 18:00

+----+---------+---------------------+---------------------+
| 4  | 3       | 2013-03-20 06:00:00 | 2013-03-20 18:00:00 |
+----+---------+---------------------+---------------------+

我可以轻松选择可用于任何给定时间戳的用户:

SELECT * FROM "public"."availability"
  WHERE ('2013-03-19 08:35:00' BETWEEN starts_at AND ends_at 
     AND '2013-03-19 18:25:00' BETWEEN starts_at AND ends_at)
    OR  ('2013-03-20 12:00:00' BETWEEN starts_at AND ends_at
     AND '2013-03-20 18:00:00' BETWEEN starts_at AND ends_at);

+----+---------+---------------------+---------------------+
| id | user_id | starts_at           | ends_at             |
+----+---------+---------------------+---------------------+
| 3  | 2       | 2013-03-17 00:00:00 | 2013-03-23 23:59:59 |
+----+---------+---------------------+---------------------+
| 4  | 3       | 2013-03-20 06:00:00 | 2013-03-20 18:00:00 |
+----+---------+---------------------+---------------------+

但我真正需要的是能够查询多个时间盘并仅返回匹配所有条件的user_ids.

查询:2013-03-17 10:00:00-2013-03-17 16:00:00,2013-03-23 10:00:00-2013-03-23 16:00:00应该返回:

+----+---------+---------------------+---------------------+
| id | user_id | starts_at           | ends_at             |
+----+---------+---------------------+---------------------+
| 3  | 2       | 2013-03-17 00:00:00 | 2013-03-23 23:59:59 |
+----+---------+---------------------+---------------------+

查询:2013-03-18 09:00:00-2013-03-18 16:00:00,2013-03-19 08:00:00-2013-03-19 15:45:00应该返回:

+----+---------+---------------------+---------------------+
| id | user_id | starts_at           | ends_at             |
+----+---------+---------------------+---------------------+
| 1  | 1       | 2013-03-18 08:00:00 | 2013-03-18 17:00:00 |
+----+---------+---------------------+---------------------+
| 2  | 1       | 2013-03-19 08:00:00 | 2013-03-19 17:00:00 |
+----+---------+---------------------+---------------------+
| 3  | 2       | 2013-03-17 00:00:00 | 2013-03-23 23:59:59 |
+----+---------+---------------------+---------------------+

查询:2013-03-18 07:00:00-2013-03-18 18:00:00应该什么都不返回.

SQLFiddle example

解决方法

SQL Fiddle

这会将boolean强制转换为整数0或1.

select a.*
from
    availability a
    inner join
    (
        select
            user_id,sum (
                ('2013-03-18 09:00:00' between starts_at and ends_at
                 and
                 '2013-03-18 16:00:00' between starts_at and ends_at
                )::integer
                +
                ('2013-03-19 08:00:00' between starts_at and ends_at
                 and
                 '2013-03-19 15:45:00' between starts_at and ends_at
                )::integer
            ) period
        from availability
        group by user_id
    ) s on a.user_id = s.user_id
where period >= 2

将where条件更改为要匹配的句点数.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读