postgresql - 不确定如何在时间段之间获得空置单位
问题描述
不知道如何设置条件(或者是否需要操作;对于 SQL 来说是新鲜的)来查找空单元。
单位附有租赁的开始和结束日期。
INSERT INTO lease (unit, s_date, e_date) VALUES (1, '20200101','20200530');
INSERT INTO lease (unit, s_date, e_date) VALUES (2, '20200701','20201231');
INSERT INTO lease (unit, s_date, e_date) VALUES (3, '20200201','20210501');
INSERT INTO lease (unit, s_date, e_date) VALUES (4, '20200615','20201225');
即在 2020/06/01-30 之间,单元#1 和 2 是空置的并且应该显示。
然而,
SELECT * FROM lease WHERE (s_date NOT BETWEEN '20200601' AND '20200630') AND (e_date NOT BETWEEN '20200601' AND '20200630');
结果也显示了第 3 单元
提前致谢!
解决方案
您的表定义不好:
切勿使用日期以外的数据类型
date
。字符串和数字都不合适。用于
daterange
存储日期间隔。
所以这应该是:
CREATE TABLE lease (
unit bigint NOT NULL,
leased daterange NOT NULL
);
INSERT INTO lease VALUES (1, '[2020-01-01,2020-05-30]');
...
那么您的查询将是:
SELECT unit
FROM lease
GROUP BY unit
HAVING NOT range_agg(leased) && '[2020-06-01,2020-06-30]';
这需要 PostgreSQL v14 的多范围支持。&&
是“重叠”运算符。
使用 PostgreSQL v13 及以下版本,您可以使用:
SELECT unit
FROM lease
EXCEPT
SELECT unit
FROM lease
WHERE leased && '[2020-06-01,2020-06-30]';
请注意,即使您不在daterange
表中使用,也可以使用此解决方案,因为您可以daterange
在查询中使用该函数:
SELECT daterange('2020-01-01', '2020-05-30', '[]');
daterange
═════════════════════════
[2020-01-01,2020-05-31)
(1 row)
推荐阅读
- javascript - 如何获取节点模块 js/json 配置文件的自动完成功能
- microsoft-teams - 如何使用消息扩展在任务模块中进行身份验证
- node.js - 连接字符串中有多个 url 的 MongoDb 行为
- makefile - 为什么 $(INSTALL_BIN) 和 $(INSTALL_DATA) 在 Makefile 中安装文件时总是删除软链接
- java - 具有 Java 向后兼容性的 Kotlin 可选参数
- javascript - Listengin 提交表单 - Javascript
- flutter - StreamProvider:避免重复构建
- c# - 使用 System.Text.Json 将 IConfiguration 序列化回 Json
- python - 在 extras_require 中声明可选依赖项
- python - 如何在不使用 turtle.mainloop() 的情况下停止海龟冻结?